Skip to content

Commit

Permalink
feat: add a home page (#11)
Browse files Browse the repository at this point in the history
* chore(libs): remove unused jsdom library

* feat(home): add empty home page

* feat(home): add unsorted sprouts list

* feat(cultivating): add sprout details dialog component

* feat(home): add a learn button to the home page

* feat(home): add a button and dialog to add new seeds

* feat(home): add last seeds list

* feat(planting): remove old new seed component

* feat(home, planting): add AddTermsButtonComponent that wraps both a button and a modal, use it also on planting page

* fix(routing): fix wildcart redirect
  • Loading branch information
artaommahe authored Aug 25, 2024
1 parent b9ebd9d commit f5cbd8d
Show file tree
Hide file tree
Showing 16 changed files with 260 additions and 528 deletions.
373 changes: 0 additions & 373 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,11 @@ export const routes: Routes = [
path: 'settings',
loadChildren: () => import('./settings/settings.routes').then(m => m.settingsRoutes),
},
{ path: '', redirectTo: '/planting', pathMatch: 'full' },
{
path: '',
loadChildren: () => import('./home/home.routes').then(m => m.homeRoutes),
},

// rest
{ path: '**', redirectTo: '/' },
];
25 changes: 4 additions & 21 deletions src/app/cultivating/cultivating-page.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/cor

import { BarnService } from '../barn/barn.service';
import { LearnCardsComponent } from '../learning/learn-cards.component';
import { DialogComponent } from '../ui/dialog/dialog.component';
import { SproutDetailsComponent, type SproutDetailsSprout } from './sprout-details/sprout-details.component';
import { SproutDetailsDialogComponent } from './sprout-details-dialog/sprout-details-dialog.component';
import { type SproutDetailsSprout } from './sprout-details/sprout-details.component';
import { SproutsListComponent } from './sprouts-list/sprouts-list.component';

@Component({
Expand All @@ -15,18 +15,11 @@ import { SproutsListComponent } from './sprouts-list/sprouts-list.component';
<app-sprouts-list [sprouts]="sprouts() ?? []" (showDetails)="onShowDetails($event)" />
@if (sproutDetails(); as sprout) {
<app-dialog (close)="sproutDetails.set(null)">
<app-sprout-details
[sprout]="sprout"
(cancel)="sproutDetails.set(null)"
(remove)="onRemoveSprout(sprout.id)"
(update)="onUpdateSprout(sprout.id, $event)"
/>
</app-dialog>
<app-sprout-details-dialog [sprout]="sprout" (close)="sproutDetails.set(null)" />
}
</div>
`,
imports: [SproutsListComponent, SproutDetailsComponent, DialogComponent, LearnCardsComponent],
imports: [SproutsListComponent, SproutDetailsDialogComponent, LearnCardsComponent],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
})
Expand All @@ -45,14 +38,4 @@ export class CultivatingPageComponent {

this.sproutDetails.set(sprout);
}

onRemoveSprout(id: string) {
this.barnService.removeSprout(id);
this.sproutDetails.set(null);
}

onUpdateSprout(id: string, value: Partial<SproutDetailsSprout>) {
this.barnService.updateSprout(id, value);
this.sproutDetails.set(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { ChangeDetectionStrategy, Component, inject, input, output } from '@angular/core';

import { BarnService } from '../../barn/barn.service';
import { DialogComponent } from '../../ui/dialog/dialog.component';
import { SproutDetailsComponent, type SproutDetailsSprout } from '../sprout-details/sprout-details.component';

@Component({
selector: 'app-sprout-details-dialog',
template: `
<app-dialog (close)="close.emit()">
<app-sprout-details
[sprout]="sprout()"
(cancel)="close.emit()"
(remove)="onRemoveSprout(sprout().id)"
(update)="onUpdateSprout(sprout().id, $event)"
/>
</app-dialog>
`,
imports: [DialogComponent, SproutDetailsComponent],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SproutDetailsDialogComponent {
private barnService = inject(BarnService);

sprout = input.required<SproutDetailsSprout>();

close = output();

onRemoveSprout(id: string) {
this.barnService.removeSprout(id);
this.close.emit();
}

onUpdateSprout(id: string, value: Partial<SproutDetailsSprout>) {
this.barnService.updateSprout(id, value);
this.close.emit();
}
}
23 changes: 23 additions & 0 deletions src/app/home/add-terms-button/add-terms-button.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';

import { IconComponent } from '../../ui/icon/icon';
import { AddTermsDialogComponent } from '../add-terms-dialog/add-terms-dialog.component';

@Component({
selector: 'app-add-terms-button',
template: `
<button class="fixed bottom-16 right-6" title="Add" (click)="showAddTermsDialog.set(true)">
<app-icon class="size-10 text-action-primary" name="plusInCircle" />
</button>
@if (showAddTermsDialog()) {
<app-add-terms-dialog (close)="showAddTermsDialog.set(false)" />
}
`,
imports: [IconComponent, AddTermsDialogComponent],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AddTermsButtonComponent {
showAddTermsDialog = signal(false);
}
56 changes: 56 additions & 0 deletions src/app/home/add-terms-dialog/add-terms-dialog.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { ChangeDetectionStrategy, Component, inject, output, signal } from '@angular/core';

import { BarnService } from '../../barn/barn.service';
import { ButtonDirective } from '../../ui/button/button';
import { DialogComponent } from '../../ui/dialog/dialog.component';
import { InputDirective } from '../../ui/input/input';

@Component({
selector: 'app-add-terms-dialog',
template: `
<app-dialog (close)="close.emit()">
<div class="flex h-full flex-col gap-8 pt-10">
<textarea
class="grow"
appInput
placeholder="One seed a line"
autocapitalize="off"
[value]="newSeed()"
(input)="updateSeed($event)"
></textarea>
<div class="mt-auto flex shrink-0 justify-end gap-4">
<button appButton (click)="close.emit()">Cancel</button>
<button appButton appButtonType="primary" (click)="add()">Add</button>
</div>
</div>
</app-dialog>
`,
imports: [DialogComponent, ButtonDirective, InputDirective],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AddTermsDialogComponent {
private barnService = inject(BarnService);

close = output();

newSeed = signal('');

updateSeed(event: Event) {
this.newSeed.set((event.target as HTMLTextAreaElement).value);
}

add() {
const newSeeds = this.newSeed()
.split('\n')
.map(seed => seed.trim())
.filter(seed => !!seed);

if (newSeeds.length !== 0) {
this.barnService.addSeeds(newSeeds);
}

this.close.emit();
}
}
25 changes: 25 additions & 0 deletions src/app/home/home-page.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { LearnCardsComponent } from '../learning/learn-cards.component';
import { AddTermsButtonComponent } from './add-terms-button/add-terms-button.component';
import { LastSeedsListComponent } from './last-seeds-list/last-seeds-list.component';
import { UnsortedSproutsComponent } from './unsorted-sprouts/unsorted-sprouts.component';

@Component({
selector: 'app-home-page',
template: `
<div class="flex flex-col gap-4">
<app-unsorted-sprouts />
<app-learn-cards />
<app-last-seeds-list />
<app-add-terms-button />
</div>
`,
imports: [UnsortedSproutsComponent, LearnCardsComponent, AddTermsButtonComponent, LastSeedsListComponent],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HomePageComponent {}
9 changes: 9 additions & 0 deletions src/app/home/home.routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Routes } from '@angular/router';

export const homeRoutes: Routes = [
{
path: '',
title: 'Akker',
loadComponent: () => import('./home-page.component').then(m => m.HomePageComponent),
},
];
35 changes: 35 additions & 0 deletions src/app/home/last-seeds-list/last-seeds-list.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';

import { BarnService } from '../../barn/barn.service';

@Component({
selector: 'app-last-seeds-list',
template: `
<section>
<h2 class="text-lg text-secondary">Last seeds</h2>
<ul class="columns-2 gap-4">
@for (seed of lastAddedSeeds(); track seed.name) {
<li class="w-full truncate px-2 py-1">
{{ seed.name }}
</li>
}
</ul>
</section>
`,
imports: [],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LastSeedsListComponent {
private barnService = inject(BarnService);

lastAddedSeeds = computed(() =>
this.barnService
.seeds()
?.toSorted((a, b) => b.lastAddedAt.localeCompare(a.lastAddedAt))
.slice(0, lastSeedsCount),
);
}

const lastSeedsCount = 10;
44 changes: 44 additions & 0 deletions src/app/home/unsorted-sprouts/unsorted-sprouts.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';

import { BarnService } from '../../barn/barn.service';
import { SproutDetailsDialogComponent } from '../../cultivating/sprout-details-dialog/sprout-details-dialog.component';
import { type SproutDetailsSprout } from '../../cultivating/sprout-details/sprout-details.component';

@Component({
selector: 'app-unsorted-sprouts',
template: `
@if (someUnsortedSprouts().length > 0) {
<section class="min-w-0 flex-grow">
<h2 class="text-lg text-secondary">Unsorted sprouts ({{ unsortedSproutsAmount() }})</h2>
<ul class="columns-2 gap-4">
@for (sprout of someUnsortedSprouts(); track sprout.id) {
<li>
<button class="w-full truncate px-2 py-1 text-left" (click)="sproutDetails.set(sprout)">
{{ sprout.term }}
</button>
</li>
}
</ul>
</section>
@if (sproutDetails(); as sprout) {
<app-sprout-details-dialog [sprout]="sprout" (close)="sproutDetails.set(null)" />
}
}
`,
imports: [SproutDetailsDialogComponent],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class UnsortedSproutsComponent {
private barnService = inject(BarnService);
private unsortedSprouts = computed(() => this.barnService.sprouts()?.filter(sprout => !sprout.definition));

unsortedSproutsAmount = computed(() => this.unsortedSprouts()?.length ?? 0);
someUnsortedSprouts = computed(() => this.unsortedSprouts()?.slice(0, someUnsortedSproutsAmount) ?? []);

sproutDetails = signal<SproutDetailsSprout | null>(null);
}

const someUnsortedSproutsAmount = 10;
26 changes: 14 additions & 12 deletions src/app/layout/layout.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@ import { RouterLink, RouterLinkActive } from '@angular/router';
selector: 'app-layout',
template: `
<div class="flex h-dvh flex-col overflow-hidden bg-primary text-primary">
<main class="grow overflow-y-auto p-5">
<main class="relative grow overflow-y-auto p-5">
<ng-content />
</main>
<nav class="shrink-0 border-t border-primary/10 px-2">
<ul class="flex justify-between gap-2">
@for (link of navigationLinks; track link.path) {
<li>
<!-- TODO: fix important usage -->
<a class="block p-3 text-secondary" [routerLink]="link.path" routerLinkActive="!text-primary">
{{ link.label }}
</a>
</li>
}
</ul>
<nav class="flex shrink-0 justify-between gap-2 border-t border-primary/10 px-2">
@for (link of navigationLinks; track link.path) {
<!-- TODO: fix important usage -->
<a
class="block p-3 text-secondary"
[routerLink]="link.path"
routerLinkActive="!text-primary"
[routerLinkActiveOptions]="link.options ?? { exact: false }"
>
{{ link.label }}
</a>
}
</nav>
</div>
`,
Expand All @@ -29,6 +30,7 @@ import { RouterLink, RouterLinkActive } from '@angular/router';
})
export class LayoutComponent {
navigationLinks = [
{ path: '/', label: 'Home', options: { exact: true } },
{ path: '/planting', label: 'Planting' },
{ path: '/cultivating', label: 'Cultivating' },
{ path: '/settings', label: 'Settings' },
Expand Down
3 changes: 0 additions & 3 deletions src/app/planting/new-seed/assets/input.svg

This file was deleted.

3 changes: 0 additions & 3 deletions src/app/planting/new-seed/assets/multiline-input.svg

This file was deleted.

Loading

0 comments on commit f5cbd8d

Please sign in to comment.