All files / app/pages/shopping-list shopping-lists.html

42.5% Statements 51/120
28.57% Branches 4/14
33.33% Functions 1/3
47.88% Lines 34/71

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 1211x       2x 1x   2x       1x 2x     2x   1x 2x 1x     1x 2x 1x         2x       1x 2x 2x     2x       2x       1x                                                                                                         1x 1x 2x 2x 4x   4x 4x 4x     4x   4x 4x 4x     1x   1x  
<section class="shopping-lists-page">
	<header class="lists-header">
		<div class="lists-header-content">
			<div class="lists-title-row">
				<h1 class="lists-title">{{ 'shoppingLists.title' | transloco }}</h1>
				<span
					class="connection-badge"
					[class.online]="isOnline()"
					[class.offline]="!isOnline()"
					[attr.aria-label]="'shoppingLists.statusAria' | transloco"
				>
					<span class="status-icon" aria-hidden="true"></span>
					<span class="status-text">{{ isOnline() ? ('common.online' | transloco) : ('common.offline' | transloco) }}</span>
				</span>
			</div>
			<p class="lists-subtitle">{{ 'shoppingLists.subtitle' | transloco }}</p>
		</div>
		<div class="lists-header-icon" aria-hidden="true">
			<lucide-icon [img]="icons.Layers" [size]="22" [strokeWidth]="2"></lucide-icon>
		</div>
	</header>
 
	<form class="create-list-form" (submit)="$event.preventDefault(); createList(nameInput)">
		<label class="sr-only" for="new-list-name">{{ 'shoppingLists.newListLabel' | transloco }}</label>
		<input
			id="new-list-name"
			#nameInput
			type="text"
			class="create-list-input"
			[placeholder]="'shoppingLists.newListPlaceholder' | transloco"
			maxlength="80"
			[formControl]="control"
		/>
		<button type="submit" class="create-list-button">
			<lucide-icon [img]="icons.Plus" [size]="18" [strokeWidth]="2.5"></lucide-icon>
			<span>{{ 'shoppingLists.add' | transloco }}</span>
		</button>
	</form>
	@if (control.invalid && control.touched) {
		<small class="error">{{ 'shoppingLists.nameRequired' | transloco }}</small>
	}
 
	@if (this.powerSync.ready$ | async) {
		@if (!this.listsLoaded()) {
			<div class="lists-grid skeleton-grid" aria-busy="true" role="status">
				<span class="sr-only">{{ 'shoppingLists.loadingTitle' | transloco }}</span>
				@for (i of [0, 1, 2, 3]; track i) {
					<article class="list-card skeleton" aria-hidden="true">
						<div class="list-card-main">
							<div class="list-icon skeleton-block"></div>
							<div class="list-text">
								<div class="skeleton-line skeleton-line--title"></div>
								<div class="skeleton-line skeleton-line--small"></div>
								<div class="skeleton-line skeleton-line--medium"></div>
							</div>
						</div>
						<div class="list-card-action" aria-hidden="true">
							<div class="skeleton-circle skeleton-circle--sm"></div>
						</div>
					</article>
				}
			</div>
		} @else if (this.lists().length > 0) {
			<div class="lists-grid">
				@for (list of this.lists(); track list.id) {
					<article class="list-card" (click)="openList(list)">
						<div class="list-card-main">
							<div class="list-icon" aria-hidden="true">
								<lucide-icon [img]="icons.ListChecks" [size]="18" [strokeWidth]="2"></lucide-icon>
							</div>
							<div class="list-text">
								<h2 class="list-name">{{ list.name }}</h2>
								@if (list.other_users_count != null && list.other_users_count > 0) {
									<p class="list-collaboration">{{ (list.other_users_count === 1 ? 'shoppingLists.otherUsersOne' : 'shoppingLists.otherUsersMany') | transloco : { count: list.other_users_count } }}</p>
								} @else {
									<p class="list-collaboration solo">{{ 'shoppingLists.solo' | transloco }}</p>
								}
								@if (list.description) {
									<p class="list-description">{{ list.description }}</p>
								} @else {
									<p class="list-description placeholder">{{ 'shoppingLists.noDescription' | transloco }}</p>
								}
							</div>
						</div>
						<div class="list-card-action" aria-hidden="true">
							<lucide-icon [img]="icons.ArrowRight" [size]="18" [strokeWidth]="2"></lucide-icon>
						</div>
					</article>
				}
			</div>
		} @else {
			<div class="empty-state">
				<div class="empty-state-icon" aria-hidden="true">
					<lucide-icon [img]="icons.ListChecks" [size]="30" [strokeWidth]="2"></lucide-icon>
				</div>
				<h2>{{ 'shoppingLists.emptyTitle' | transloco }}</h2>
				<p>{{ 'shoppingLists.emptySubtitle' | transloco }}</p>
			</div>
		}
	} @else {
		<div class="lists-grid skeleton-grid" aria-busy="true" role="status">
			<span class="sr-only">{{ 'shoppingLists.loadingTitle' | transloco }}</span>
			@for (i of [0, 1, 2, 3]; track i) {
				<article class="list-card skeleton" aria-hidden="true">
					<div class="list-card-main">
						<div class="list-icon skeleton-block"></div>
						<div class="list-text">
							<div class="skeleton-line skeleton-line--title"></div>
							<div class="skeleton-line skeleton-line--small"></div>
							<div class="skeleton-line skeleton-line--medium"></div>
						</div>
					</div>
					<div class="list-card-action" aria-hidden="true">
						<div class="skeleton-circle skeleton-circle--sm"></div>
					</div>
				</article>
			}
		</div>
	}
</section>