Homepage: restored original v0 design, replaced lorem ipsum with real service descriptions, added BusinessHours (Opening Hours) section, alternating bg-gray-50 section backgrounds. Layout: added global sticky footer (hidden on /admin/schedule, /account, and ?format=pdf pages), wrapped content in min-h-screen flex layout. PortfolioCarousel: set heading to Playfair Display.
183 lines
7.7 KiB
Svelte
183 lines
7.7 KiB
Svelte
<script lang="ts">
|
|
import { goto } from '$app/navigation';
|
|
import { resolve } from '$app/paths';
|
|
import { Button } from '$lib/components/ui/button';
|
|
import PortfolioCarousel from '$lib/components/layout/PortfolioCarousel.svelte';
|
|
import BusinessHours from '$lib/components/layout/BusinessHours.svelte';
|
|
import { authStore } from '$lib/stores/auth.svelte';
|
|
import { Skeleton } from '$lib/components/ui/skeleton';
|
|
|
|
// Redirect admins to /today (their homepage)
|
|
$effect(() => {
|
|
if (!authStore.isLoading && authStore.currentUser?.role === 'admin') {
|
|
// eslint-disable-next-line svelte/no-navigation-without-resolve
|
|
goto('/today', { replaceState: true });
|
|
}
|
|
});
|
|
|
|
const returningGreetings = [
|
|
(name: string) => `Welcome back, ${name}!`,
|
|
(name: string) => `Great to see you again, ${name}!`,
|
|
(name: string) => `Good to have you back, ${name}!`,
|
|
(name: string) => `Hey, you're back, ${name}!`,
|
|
(name: string) => `Lovely to see you again, ${name}!`,
|
|
(name: string) => `We missed you, ${name}!`,
|
|
(name: string) => `${name}, it's so good to see you!`,
|
|
(name: string) => `${name}, welcome back to Crussell Nails!`,
|
|
(name: string) => `Always a pleasure, ${name}!`,
|
|
(name: string) => `${name}, you're a sight for sore eyes!`,
|
|
(name: string) => `So happy you're back, ${name}!`,
|
|
(name: string) => `You're back! Great to see you, ${name}!`,
|
|
(name: string) => `${name}, you've been missed!`,
|
|
(name: string) => `Ready for some pampering, ${name}?`,
|
|
(name: string) => `${name}, lovely to have you back with us!`,
|
|
(name: string) => `Great to have you back, ${name}!`,
|
|
(name: string) => `Back for more, ${name}?`,
|
|
(name: string) => `Ah, ${name}! Right on time!`,
|
|
(name: string) => `Welcome home, ${name}!`,
|
|
(name: string) => `${name}, we've been looking forward to seeing you!`,
|
|
(name: string) => `It's always a good day when ${name} walks in!`,
|
|
(name: string) => `${name}, your favourite nail artist is waiting!`,
|
|
(name: string) => `How wonderful to see you, ${name}!`,
|
|
(name: string) => `${name}, you're as welcome as ever!`,
|
|
(name: string) => `Another visit, ${name}? You spoil us!`,
|
|
(name: string) => `${name}, you always brighten up our day!`,
|
|
(name: string) => `Great timing, ${name} — let's get started!`,
|
|
(name: string) => `${name}, you deserve every bit of this!`,
|
|
(name: string) => `So glad you're here again, ${name}!`,
|
|
(name: string) => `Look who it is — the wonderful ${name}!`
|
|
];
|
|
|
|
const unverifiedGreetings = [
|
|
(name: string) => `Welcome, ${name}!`,
|
|
(name: string) => `Hi, ${name}! Great to meet you!`,
|
|
(name: string) => `Hey ${name}, welcome aboard!`,
|
|
(name: string) => `Hello, ${name}! Lovely to have you here!`,
|
|
(name: string) => `Good to meet you, ${name}!`,
|
|
(name: string) => `${name}, welcome to Crussell Nails!`,
|
|
(name: string) => `Hi ${name}, we're so glad you're here!`,
|
|
(name: string) => `Welcome in, ${name}!`,
|
|
(name: string) => `${name}, it's great to have you with us!`,
|
|
(name: string) => `Hello ${name}, glad you found us!`,
|
|
(name: string) => `${name}, welcome — you're going to love it here!`,
|
|
(name: string) => `Nice to meet you, ${name}!`,
|
|
(name: string) => `${name}, welcome to the family!`,
|
|
(name: string) => `Hey ${name}, so happy to have you here!`,
|
|
(name: string) => `${name}, you've come to the right place!`,
|
|
(name: string) => `Welcome, ${name} — we're thrilled to have you!`,
|
|
(name: string) => `${name}, let's get you pampered!`,
|
|
(name: string) => `Great to have you here, ${name}!`,
|
|
(name: string) => `${name}, welcome — something beautiful awaits!`,
|
|
(name: string) => `${name}, your journey to great nails starts here!`,
|
|
(name: string) => `So excited to have you here, ${name}!`,
|
|
(name: string) => `${name}, we can't wait to show you what we do!`,
|
|
(name: string) => `A big welcome to you, ${name}!`,
|
|
(name: string) => `${name}, we're so glad you chose Crussell Nails!`,
|
|
(name: string) => `Hi ${name}, you're in great hands here!`,
|
|
(name: string) => `${name}, this is the beginning of something beautiful!`,
|
|
(name: string) => `Welcome ${name} — you picked the perfect place!`,
|
|
(name: string) => `${name}, we love meeting new faces!`,
|
|
(name: string) => `${name}, we're delighted to have you with us!`,
|
|
(name: string) => `Hello ${name}, great things are ahead!`,
|
|
(name: string) => `${name}, we're already excited to look after you!`,
|
|
(name: string) => `Welcome ${name} — you're going to fit right in!`,
|
|
(name: string) => `So glad you're here, ${name}!`,
|
|
(name: string) => `${name}, you've made an excellent choice today!`,
|
|
(name: string) => `Welcome to the club, ${name}!`
|
|
];
|
|
|
|
function getRandomGreeting(name: string, isReturning: boolean): string {
|
|
const greetings = isReturning ? returningGreetings : unverifiedGreetings;
|
|
const randomIndex = Math.floor(Math.random() * greetings.length);
|
|
return greetings[randomIndex](name);
|
|
}
|
|
</script>
|
|
|
|
<svelte:head>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous" />
|
|
<link
|
|
href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap"
|
|
rel="stylesheet"
|
|
/>
|
|
</svelte:head>
|
|
|
|
<section class="py-20 text-center">
|
|
{#if authStore.isLoading}
|
|
<div class="m-2 mb-4">
|
|
<Skeleton class="mx-auto h-10 w-80 max-w-full" />
|
|
</div>
|
|
<div class="mb-8">
|
|
<Skeleton class="mx-auto h-6 w-96 max-w-full" />
|
|
</div>
|
|
<Skeleton class="mx-auto h-12 w-48" />
|
|
{:else}
|
|
<h1 class="m-2 mb-4 font-['Playfair_Display'] text-4xl font-bold">
|
|
{#if !authStore.isAuthenticated}
|
|
Welcome to Crussell Nails
|
|
{:else if authStore.currentUser?.role === 'unverified_email'}
|
|
{getRandomGreeting(authStore.currentUser?.firstName || '', false)}
|
|
{:else}
|
|
{getRandomGreeting(authStore.currentUser?.firstName || '', true)}
|
|
{/if}
|
|
</h1>
|
|
<p class="mb-8 text-lg text-gray-600">
|
|
Professional beauty treatments in a calm and friendly environment.
|
|
</p>
|
|
|
|
{#if authStore.currentUser?.role === 'admin'}
|
|
<Button href={resolve('/today')} class="px-6 py-3 text-lg">View your day</Button>
|
|
{:else}
|
|
<Button href={resolve('/book')} class="px-6 py-3 text-lg">Book an Appointment</Button>
|
|
{/if}
|
|
{/if}
|
|
</section>
|
|
|
|
<section class="bg-gray-50">
|
|
<div class="mx-auto max-w-4xl px-6 py-16">
|
|
<h2 class="mb-8 text-center font-['Playfair_Display'] text-2xl font-semibold">Our Services</h2>
|
|
<div class="grid grid-cols-1 gap-8 md:grid-cols-4">
|
|
<div class="rounded-lg border p-6">
|
|
<h3 class="mb-2 text-lg font-semibold">Hands</h3>
|
|
<p class="text-gray-600">
|
|
Gel polish, nail art, and natural nail care — finished with a soothing hand massage.
|
|
</p>
|
|
</div>
|
|
<div class="rounded-lg border p-6">
|
|
<h3 class="mb-2 text-lg font-semibold">Feet</h3>
|
|
<p class="text-gray-600">
|
|
Luxurious pedicures with exfoliation, cuticle care, and a long-lasting polish finish.
|
|
</p>
|
|
</div>
|
|
<div class="rounded-lg border p-6">
|
|
<h3 class="mb-2 text-lg font-semibold">Brows</h3>
|
|
<p class="text-gray-600">
|
|
Expert shaping, tinting, and lamination for brows that frame your face perfectly.
|
|
</p>
|
|
</div>
|
|
<div class="rounded-lg border p-6">
|
|
<h3 class="mb-2 text-lg font-semibold">Wax</h3>
|
|
<p class="text-gray-600">
|
|
Gentle waxing for face, body, and brows — smooth results with minimal discomfort.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<PortfolioCarousel />
|
|
|
|
<section class="bg-gray-50">
|
|
<div class="mx-auto max-w-4xl px-6 py-16">
|
|
<h2 class="mb-8 text-center font-['Playfair_Display'] text-2xl font-semibold">Opening Hours</h2>
|
|
<BusinessHours />
|
|
</div>
|
|
</section>
|
|
|
|
<section class="py-20 text-center">
|
|
<h2 class="mb-4 font-['Playfair_Display'] text-2xl font-semibold">Ready to Treat Yourself?</h2>
|
|
<Button href={resolve('/prices')} class="px-6 py-3 text-lg">View Price List</Button>
|
|
</section>
|
|
|
|
|