Add login, role-based portals, and browser-local admin image upload
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
|
||||
const reservations = [
|
||||
{ id: 1, date: '2026-07-12', time: '19:00', guests: 4, table: 'Terrace 3' },
|
||||
{ id: 2, date: '2026-07-25', time: '20:30', guests: 2, table: 'Barrel 7' },
|
||||
];
|
||||
|
||||
const coupons = [
|
||||
{ code: 'WELCOME20', discount: '20% off your next stay' },
|
||||
{ code: 'COFFEE5', discount: '$5 off any coffee tasting' },
|
||||
];
|
||||
|
||||
const offers = [
|
||||
{ title: 'Summer Wine Weekend', desc: 'Complimentary wine tasting with every two-night stay.' },
|
||||
{ title: 'Sunset Dinner', desc: 'Three-course menu on the terrace every Friday.' },
|
||||
];
|
||||
|
||||
const benefits = [
|
||||
'Priority booking for peak weekends',
|
||||
'Late checkout on availability',
|
||||
'Free welcome cocktail',
|
||||
'Member-only events and tastings',
|
||||
];
|
||||
|
||||
export default function UserPage() {
|
||||
const { isUser, hydrated } = useAuth();
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (!hydrated) return;
|
||||
if (!isUser) {
|
||||
router.push('/login');
|
||||
}
|
||||
}, [isUser, hydrated, router]);
|
||||
|
||||
if (!hydrated || !isUser) {
|
||||
return (
|
||||
<main style={{ padding: '2rem' }}>
|
||||
<p>Please log in as user to access this page.</p>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<main style={{ padding: '2rem', maxWidth: '48rem', margin: '0 auto' }}>
|
||||
<h1>User Portal</h1>
|
||||
|
||||
<section style={{ marginBottom: '2rem' }}>
|
||||
<h2>Future Reservations</h2>
|
||||
{reservations.length === 0 ? (
|
||||
<p style={{ color: 'dimgray' }}>No upcoming reservations.</p>
|
||||
) : (
|
||||
<ul style={{ padding: 0, listStyle: 'none' }}>
|
||||
{reservations.map((r) => (
|
||||
<li
|
||||
key={r.id}
|
||||
style={{
|
||||
padding: '1rem',
|
||||
marginBottom: '0.5rem',
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: '8px',
|
||||
}}
|
||||
>
|
||||
{r.date} at {r.time} · {r.guests} guests · {r.table}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<section style={{ marginBottom: '2rem' }}>
|
||||
<h2>Discount Coupons</h2>
|
||||
<div style={{ display: 'flex', gap: '1rem', flexWrap: 'wrap' }}>
|
||||
{coupons.map((c) => (
|
||||
<div
|
||||
key={c.code}
|
||||
style={{
|
||||
padding: '1rem',
|
||||
border: '2px dashed #1a1a1a',
|
||||
borderRadius: '8px',
|
||||
minWidth: '12rem',
|
||||
}}
|
||||
>
|
||||
<strong>{c.code}</strong>
|
||||
<p style={{ margin: '0.5rem 0 0', color: 'dimgray' }}>{c.discount}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style={{ marginBottom: '2rem' }}>
|
||||
<h2>Offers</h2>
|
||||
<ul>
|
||||
{offers.map((o) => (
|
||||
<li key={o.title}>
|
||||
<strong>{o.title}</strong> — {o.desc}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section style={{ marginBottom: '2rem' }}>
|
||||
<h2>WiFi Password</h2>
|
||||
<p
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
padding: '0.75rem 1.5rem',
|
||||
background: '#f4f4f4',
|
||||
borderRadius: '8px',
|
||||
fontFamily: 'monospace',
|
||||
fontSize: '1.25rem',
|
||||
}}
|
||||
>
|
||||
LaHuascaGuest2026
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Member Benefits</h2>
|
||||
<ul>
|
||||
{benefits.map((b) => (
|
||||
<li key={b}>{b}</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user