-
Notifications
You must be signed in to change notification settings - Fork 3
Add shop countdown #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Rename production image tag to 'production' and add CI workflow for staging branch
Got it ready to deploy
Disable admin on everyone, add super admin system, clear out migrations ahead of coolify deployment
Beta channel check
Add docker compose files for coolify
User admin page + small scaling fix
Devlog count bug fix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds a countdown timer to the market page to display when the shop will open. The countdown is implemented using Svelte 5's reactive state management with proper lifecycle hooks for cleanup.
Key changes:
- Implements a countdown timer that updates every second until a target date (December 15, 2025)
- Uses Svelte lifecycle hooks (
onMount,onDestroy) for proper interval management - Adds a responsive UI component displaying days, hours, minutes, and seconds
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
| let { data } = $props(); | ||
| let timeLeft = $state({ days: 0, hours: 0, minutes: 0, seconds: 0 }); | ||
| let interval: ReturnType<typeof setInterval>; | ||
| const targetDate = new Date('2025-12-15T23:59:00-05:00').getTime(); |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The target date is hardcoded. Consider moving this to a configuration file, environment variable, or making it dynamically fetched from the backend. This will make it easier to update the shop opening date without code changes.
| let { data } = $props(); | |
| let timeLeft = $state({ days: 0, hours: 0, minutes: 0, seconds: 0 }); | |
| let interval: ReturnType<typeof setInterval>; | |
| const targetDate = new Date('2025-12-15T23:59:00-05:00').getTime(); | |
| import { PUBLIC_SHOP_OPEN_DATE } from '$env/static/public'; | |
| let { data } = $props(); | |
| let timeLeft = $state({ days: 0, hours: 0, minutes: 0, seconds: 0 }); | |
| let interval: ReturnType<typeof setInterval>; | |
| const targetDate = new Date(PUBLIC_SHOP_OPEN_DATE).getTime(); |
| <div class="my-12 flex flex-col items-center justify-center"> | ||
| <h2 class="mb-6 font-hero text-xl text-primary-300 md:text-2xl">Shop Opens In</h2> |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the countdown reaches zero, the message "Shop Opens In" may be confusing since the shop should now be open. Consider conditionally rendering different content after the countdown completes, such as "Shop is Now Open!" or hiding the countdown entirely.
| <div class="my-12 flex flex-col items-center justify-center"> | ||
| <h2 class="mb-6 font-hero text-xl text-primary-300 md:text-2xl">Shop Opens In</h2> | ||
| <div class="grid grid-cols-2 gap-4 text-center font-hero text-primary-50 md:grid-cols-4"> |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The countdown timer updates every second, which may cause screen readers to constantly announce changes. Consider adding aria-live="polite" to the countdown container and possibly throttling announcements (e.g., only announcing significant changes like minute updates) for better accessibility.
| <div class="themed-box flex min-w-[120px] flex-col items-center justify-center p-4"> | ||
| <span class="mb-2 text-4xl md:text-5xl">{timeLeft.days}</span> | ||
| <span class="text-xs text-primary-400 md:text-sm">DAYS</span> | ||
| </div> | ||
| <div class="themed-box flex min-w-[120px] flex-col items-center justify-center p-4"> | ||
| <span class="mb-2 text-4xl md:text-5xl">{timeLeft.hours}</span> | ||
| <span class="text-xs text-primary-400 md:text-sm">HOURS</span> | ||
| </div> | ||
| <div class="themed-box flex min-w-[120px] flex-col items-center justify-center p-4"> | ||
| <span class="mb-2 text-4xl md:text-5xl">{timeLeft.minutes}</span> | ||
| <span class="text-xs text-primary-400 md:text-sm">MINS</span> | ||
| </div> | ||
| <div class="themed-box flex min-w-[120px] flex-col items-center justify-center p-4"> | ||
| <span class="mb-2 text-4xl md:text-5xl">{timeLeft.seconds}</span> | ||
| <span class="text-xs text-primary-400 md:text-sm">SECS</span> | ||
| </div> |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The four time unit boxes have duplicated markup. Consider refactoring this into a reusable component or using an array with {#each} block to reduce code duplication and improve maintainability. For example:
{#each [
{ value: timeLeft.days, label: 'DAYS' },
{ value: timeLeft.hours, label: 'HOURS' },
{ value: timeLeft.minutes, label: 'MINS' },
{ value: timeLeft.seconds, label: 'SECS' }
] as unit}
<div class="themed-box flex min-w-[120px] flex-col items-center justify-center p-4">
<span class="mb-2 text-4xl md:text-5xl">{unit.value}</span>
<span class="text-xs text-primary-400 md:text-sm">{unit.label}</span>
</div>
{/each}| <div class="themed-box flex min-w-[120px] flex-col items-center justify-center p-4"> | |
| <span class="mb-2 text-4xl md:text-5xl">{timeLeft.days}</span> | |
| <span class="text-xs text-primary-400 md:text-sm">DAYS</span> | |
| </div> | |
| <div class="themed-box flex min-w-[120px] flex-col items-center justify-center p-4"> | |
| <span class="mb-2 text-4xl md:text-5xl">{timeLeft.hours}</span> | |
| <span class="text-xs text-primary-400 md:text-sm">HOURS</span> | |
| </div> | |
| <div class="themed-box flex min-w-[120px] flex-col items-center justify-center p-4"> | |
| <span class="mb-2 text-4xl md:text-5xl">{timeLeft.minutes}</span> | |
| <span class="text-xs text-primary-400 md:text-sm">MINS</span> | |
| </div> | |
| <div class="themed-box flex min-w-[120px] flex-col items-center justify-center p-4"> | |
| <span class="mb-2 text-4xl md:text-5xl">{timeLeft.seconds}</span> | |
| <span class="text-xs text-primary-400 md:text-sm">SECS</span> | |
| </div> | |
| {#each [ | |
| { value: timeLeft.days, label: 'DAYS' }, | |
| { value: timeLeft.hours, label: 'HOURS' }, | |
| { value: timeLeft.minutes, label: 'MINS' }, | |
| { value: timeLeft.seconds, label: 'SECS' } | |
| ] as unit} | |
| <div class="themed-box flex min-w-[120px] flex-col items-center justify-center p-4"> | |
| <span class="mb-2 text-4xl md:text-5xl">{unit.value}</span> | |
| <span class="text-xs text-primary-400 md:text-sm">{unit.label}</span> | |
| </div> | |
| {/each} |
| let { data } = $props(); | ||
| let timeLeft = $state({ days: 0, hours: 0, minutes: 0, seconds: 0 }); | ||
| let interval: ReturnType<typeof setInterval>; |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The interval variable is declared but not initialized, which may cause TypeScript strict mode errors. Consider either initializing it as undefined explicitly (let interval: ReturnType<typeof setInterval> | undefined;) or using TypeScript's definite assignment assertion (let interval!: ReturnType<typeof setInterval>;). The first approach is generally safer and more explicit.
| let interval: ReturnType<typeof setInterval>; | |
| let interval: ReturnType<typeof setInterval> | undefined = undefined; |
No description provided.