Skip to content

Commit ad291b0

Browse files
committed
coba ubah lagi
1 parent e62243c commit ad291b0

2 files changed

Lines changed: 154 additions & 2 deletions

File tree

‎src/app/app.html‎

Lines changed: 146 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,146 @@
1-
��<
1+
<div class="main-wrapper">
2+
<div class="container">
3+
4+
<!-- Floating Controls -->
5+
<div class="floating-controls">
6+
7+
<!-- Time Format -->
8+
<button
9+
class="control-btn"
10+
[title]="timeFormat() === '24h' ? 'Ubah ke Format 12 Jam' : 'Ubah ke Format 24 Jam'"
11+
(click)="toggleTimeFormat()"
12+
>
13+
{{ timeFormat() }}
14+
</button>
15+
16+
<!-- Favorites -->
17+
<button
18+
class="control-btn"
19+
[class.active]="facade.showFavoritesOnly()"
20+
(click)="facade.toggleFavoritesOnly()"
21+
[title]="facade.showFavoritesOnly() ? 'Tampilkan Semua Kota' : 'Tampilkan Favorit Saja'"
22+
>
23+
❤️
24+
<span *ngIf="favoritesService.getFavoritesCount() > 0" class="badge">{{ favoritesService.getFavoritesCount() }}</span>
25+
</button>
26+
27+
<!-- Theme -->
28+
<button class="control-btn" (click)="toggleTheme()" [title]="themeService.currentTheme() === 'light' ? 'Aktifkan Dark Mode' : 'Aktifkan Light Mode'">
29+
<span *ngIf="themeService.currentTheme() === 'light'">🌙</span>
30+
<span *ngIf="themeService.currentTheme() === 'dark'">☀️</span>
31+
</button>
32+
33+
<!-- Alarm & Timer -->
34+
<button class="control-btn" (click)="showAlarmTimer.set(!showAlarmTimer())" title="Alarm & Timer">
35+
🔔⏱️
36+
</button>
37+
38+
</div>
39+
40+
<div class="header">
41+
<h1>Jam Dunia Modern</h1>
42+
</div>
43+
44+
<!-- Search Input Section -->
45+
<div class="search-section">
46+
<div class="search-container">
47+
<svg class="search-icon" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
48+
<circle cx="11" cy="11" r="8"></circle>
49+
<path d="m21 21-4.35-4.35"></path>
50+
</svg>
51+
<input
52+
type="text"
53+
class="search-input"
54+
placeholder="Cari kota..."
55+
[value]="searchService.searchQuery()"
56+
(input)="searchService.updateSearchQuery($any($event.target).value)"
57+
(keydown.escape)="searchService.clearSearch()"
58+
/>
59+
<button *ngIf="searchService.searchQuery()" class="search-clear-btn" (click)="searchService.clearSearch()" title="Clear search">
60+
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
61+
<line x1="18" y1="6" x2="6" y2="18"></line>
62+
<line x1="6" y1="6" x2="18" y2="18"></line>
63+
</svg>
64+
</button>
65+
</div>
66+
67+
<p *ngIf="searchService.searchQuery()" class="search-results-count">
68+
Ditemukan {{ facade.filteredLocations().length }} kota
69+
</p>
70+
</div>
71+
72+
<!-- Alarm & Timer Panel -->
73+
<app-alarm-timer *ngIf="showAlarmTimer()"></app-alarm-timer>
74+
75+
<!-- Timezone Converter Panel -->
76+
<app-timezone-converter></app-timezone-converter>
77+
78+
<!-- Display Result or No Results Message -->
79+
<ng-container *ngIf="facade.filteredLocations().length === 0 && searchService.searchQuery(); else clockList">
80+
<div class="no-results">
81+
<p>Tidak ada kota yang cocok dengan "<strong>{{ searchService.searchQuery() }}</strong>"</p>
82+
83+
<button class="reset-search-btn" (click)="searchService.clearSearch()">
84+
Coba Cari Lagi
85+
</button>
86+
</div>
87+
</ng-container>
88+
89+
<ng-template #clockList>
90+
<div class="clock-list" [ngClass]="getViewModeClass()">
91+
<div
92+
*ngFor="let loc of facade.filteredLocations().slice(0, facade.itemsToShow()); trackBy: trackByLocationName"
93+
class="location"
94+
[class.fade-in]="facade.getRecentlyAdded()() === loc.name"
95+
[class.fade-out]="facade.getRecentlyRemoved()() === loc.name"
96+
[class.theme-transition]="facade.getRecentlyToggledTheme()()"
97+
>
98+
<div class="location-info">
99+
<p class="city-name">{{ loc.name }}</p>
100+
<p class="time-box">
101+
{{ getFormattedTime(loc.offset) }}
102+
</p>
103+
</div>
104+
105+
<button
106+
class="favorite-btn"
107+
[class.favorited]="favoritesService.isFavorite(loc)"
108+
(click)="favoritesService.toggleFavorite(loc)"
109+
[title]="favoritesService.isFavorite(loc) ? 'Remove from favorites' : 'Add to favorites'"
110+
>
111+
<svg *ngIf="favoritesService.isFavorite(loc)" width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
112+
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
113+
</svg>
114+
<svg *ngIf="!favoritesService.isFavorite(loc)" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
115+
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
116+
</svg>
117+
</button>
118+
</div>
119+
</div>
120+
121+
<!-- Loading State -->
122+
<div *ngIf="facade.isLoading()" class="loading-container">
123+
<div class="spinner"></div>
124+
<p class="loading-text">Sedang memuat...</p>
125+
</div>
126+
127+
<!-- Load More Button -->
128+
<button *ngIf="!facade.isLoading() && facade.itemsToShow() < facade.filteredLocations().length" class="load-more-btn" (click)="facade.loadMore()" [disabled]="facade.isLoading()">
129+
<span>⧬ Muat Lebih Banyak</span>
130+
</button>
131+
132+
<!-- All Loaded Message -->
133+
<p *ngIf="facade.isAllLoaded()" class="all-loaded">✓ Semua kota telah dimuat!</p>
134+
</ng-template>
135+
136+
</div>
137+
138+
<!-- Tombol Scroll to Top Lingkaran untuk disesuaikan dengan bagian yang dibagikan dan diminta oleh departemen tersebut. -->
139+
<button class="scroll-to-top-btn" (click)="scrollToTop()" title="Kembali ke atas">
140+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
141+
<polyline points="18 15 12 9 6 15"></polyline>
142+
<line x1="12" y1="21" x2="12" y2="9"></line>
143+
</svg>
144+
</button>
145+
146+
</div>

‎src/app/app.ts‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { TimezoneConverterComponent } from './timezone-converter.component';
1212
@Component({
1313
selector: 'app-root',
1414
standalone: true,
15-
imports: [CommonModule, AlarmTimerComponent, TimezoneConverterComponent],
15+
imports: [CommonModule],
1616
templateUrl: './app.html',
1717
styleUrl: './app.css',
1818
})
@@ -201,6 +201,13 @@ export class App implements OnInit, OnDestroy {
201201
}
202202
}
203203

204+
/**
205+
* Track items by name to preserve DOM state.
206+
*/
207+
trackByLocationName(_index: number, loc: { name: string }): string {
208+
return loc.name;
209+
}
210+
204211
/**
205212
* Cleanup ketika component destroy
206213
*/

0 commit comments

Comments
 (0)