Translate invite page to italian
This commit is contained in:
@@ -5,6 +5,8 @@ import React, { useEffect, useState } from "react";
|
||||
import { useParams, useSearchParams } from "next/navigation";
|
||||
import { useGifts } from "@/context/gift-context";
|
||||
import { useGuests } from "@/context/guest-context";
|
||||
import { useEventThemes } from "@/context/event-theme-context";
|
||||
import { useEvents } from "@/context/event-context";
|
||||
import { GiftItem, GiftPurchase } from "@/client/types.gen";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
@@ -34,10 +36,11 @@ import {
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { AlertCircle, ExternalLink, Gift, Loader2 } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export default function GiftRegistryPage() {
|
||||
const { slug } = useParams<{ slug: string }>();
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
const invitationCode = searchParams.get("code");
|
||||
|
||||
@@ -64,6 +67,15 @@ export default function GiftRegistryPage() {
|
||||
} = useGifts();
|
||||
|
||||
const { findGuestByInvitationCode, guests, isLoadingGuests } = useGuests();
|
||||
const { themes, isLoadingThemes } = useEventThemes();
|
||||
const { event, fetchEventBySlug, isLoadingEvent } = useEvents();
|
||||
|
||||
// Load event data based on slug
|
||||
useEffect(() => {
|
||||
if (slug) {
|
||||
fetchEventBySlug(slug);
|
||||
}
|
||||
}, [slug, fetchEventBySlug]);
|
||||
|
||||
// Find current guest based on invitation code
|
||||
const currentGuest = invitationCode
|
||||
@@ -76,7 +88,7 @@ export default function GiftRegistryPage() {
|
||||
|
||||
if (!currentGuest) {
|
||||
setErrorMessage(
|
||||
"Invalid invitation code. Please check your invitation link.",
|
||||
"Codice invito non valido. Controlla il link dell'invito.",
|
||||
);
|
||||
setIsLoading(false);
|
||||
return;
|
||||
@@ -90,7 +102,7 @@ export default function GiftRegistryPage() {
|
||||
.catch((error) => {
|
||||
console.error("Error fetching gifts:", error);
|
||||
setErrorMessage(
|
||||
"Unable to load gift registry. Please try again later.",
|
||||
"Impossibile caricare la lista regali. Riprova più tardi.",
|
||||
);
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -108,7 +120,7 @@ export default function GiftRegistryPage() {
|
||||
console.error("Error fetching guest purchases:", error);
|
||||
});
|
||||
} else {
|
||||
setErrorMessage("No event found for this invitation.");
|
||||
setErrorMessage("Nessun evento trovato per questo invito.");
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [
|
||||
@@ -148,33 +160,58 @@ export default function GiftRegistryPage() {
|
||||
setReservedGifts(reserved);
|
||||
}
|
||||
}, [items, guestPurchases]);
|
||||
|
||||
// Find the theme for this event
|
||||
const eventTheme =
|
||||
event && themes?.find((theme) => theme.id === event.theme_id);
|
||||
|
||||
// Enhanced color palette that works well with safari animals
|
||||
const colors = eventTheme?.color_palette || {
|
||||
primary: "#90B77D", // Soft jungle green
|
||||
secondary: "#D2AB67", // Warm giraffe yellow
|
||||
accent: "#B5A9EA", // Soft hippo purple
|
||||
accent2: "#8FBDD3", // Elephant blue
|
||||
accent3: "#E8B87D", // Lion tan
|
||||
background: "#F9F5F0", // Cream paper texture
|
||||
backgroundDark: "#F0E9D6", // Slightly darker cream for panels
|
||||
text: "#5B4B49", // Warm dark brown
|
||||
textLight: "#7D6D6B", // Lighter text variant
|
||||
gold: "#D4AF37", // Gold accent for special elements
|
||||
};
|
||||
|
||||
// Font selections
|
||||
const fonts = eventTheme?.fonts || {
|
||||
heading: "Georgia, serif",
|
||||
body: "Arial, sans-serif",
|
||||
};
|
||||
|
||||
// Format priority for display
|
||||
const formatPriority = (priority: string) => {
|
||||
switch (priority) {
|
||||
case "must_have":
|
||||
return {
|
||||
label: "Must Have",
|
||||
color: "bg-red-100 text-red-800 border-red-200",
|
||||
label: "Obbligatorio",
|
||||
color: `bg-opacity-20 text-opacity-90 bg-red-100 text-red-800 border-red-200`,
|
||||
};
|
||||
case "high":
|
||||
return {
|
||||
label: "High",
|
||||
color: "bg-orange-100 text-orange-800 border-orange-200",
|
||||
label: "Alta",
|
||||
color: `bg-opacity-20 text-opacity-90 bg-orange-100 text-orange-800 border-orange-200`,
|
||||
};
|
||||
case "medium":
|
||||
return {
|
||||
label: "Medium",
|
||||
color: "bg-blue-100 text-blue-800 border-blue-200",
|
||||
label: "Media",
|
||||
color: `bg-opacity-20 text-opacity-90 bg-blue-100 text-blue-800 border-blue-200`,
|
||||
};
|
||||
case "low":
|
||||
return {
|
||||
label: "Low",
|
||||
color: "bg-green-100 text-green-800 border-green-200",
|
||||
label: "Bassa",
|
||||
color: `bg-opacity-20 text-opacity-90 bg-green-100 text-green-800 border-green-200`,
|
||||
};
|
||||
default:
|
||||
return {
|
||||
label: priority,
|
||||
color: "bg-gray-100 text-gray-800 border-gray-200",
|
||||
color: `bg-opacity-20 text-opacity-90 bg-gray-100 text-gray-800 border-gray-200`,
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -189,7 +226,7 @@ export default function GiftRegistryPage() {
|
||||
// Remove reservation handler
|
||||
const handleRemoveReservation = async (gift: GiftItem) => {
|
||||
if (!currentGuest) {
|
||||
setErrorMessage("Guest information not found.");
|
||||
setErrorMessage("Informazioni ospite non trovate.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -206,14 +243,14 @@ export default function GiftRegistryPage() {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error removing reservation:", error);
|
||||
setErrorMessage("Unable to remove reservation. Please try again.");
|
||||
setErrorMessage("Impossibile rimuovere la prenotazione. Riprova.");
|
||||
}
|
||||
};
|
||||
|
||||
// Confirm reservation handler
|
||||
const handleConfirmReservation = async () => {
|
||||
if (!selectedGift || !currentGuest) {
|
||||
setErrorMessage("Required information missing.");
|
||||
setErrorMessage("Informazioni richieste mancanti.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -235,7 +272,7 @@ export default function GiftRegistryPage() {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error reserving gift:", error);
|
||||
setErrorMessage("Unable to reserve gift. Please try again.");
|
||||
setErrorMessage("Impossibile prenotare il regalo. Riprova.");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -256,12 +293,46 @@ export default function GiftRegistryPage() {
|
||||
);
|
||||
};
|
||||
|
||||
// Animation variants
|
||||
const containerVariants = {
|
||||
hidden: { opacity: 0 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
transition: {
|
||||
staggerChildren: 0.1,
|
||||
delayChildren: 0.2,
|
||||
duration: 0.5,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const itemVariants = {
|
||||
hidden: { opacity: 0, y: 20 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: { duration: 0.5 },
|
||||
},
|
||||
};
|
||||
|
||||
// Loading state
|
||||
if (isLoading || isLoadingGuests || isLoadingItems) {
|
||||
if (
|
||||
isLoading ||
|
||||
isLoadingGuests ||
|
||||
isLoadingItems ||
|
||||
isLoadingEvent ||
|
||||
isLoadingThemes
|
||||
) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-[300px] p-8">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-primary mb-4" />
|
||||
<p className="text-muted-foreground">Loading gift registry...</p>
|
||||
<div
|
||||
className="flex flex-col items-center justify-center min-h-[300px] p-8"
|
||||
style={{ backgroundColor: colors.background }}
|
||||
>
|
||||
<Loader2
|
||||
className="h-8 w-8 animate-spin mb-4"
|
||||
style={{ color: colors.primary }}
|
||||
/>
|
||||
<p style={{ color: colors.textLight }}>Caricamento lista regali...</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -269,10 +340,10 @@ export default function GiftRegistryPage() {
|
||||
// Error state
|
||||
if (errorMessage) {
|
||||
return (
|
||||
<div className="p-8">
|
||||
<div className="p-8" style={{ backgroundColor: colors.background }}>
|
||||
<Alert variant="destructive">
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
<AlertTitle>Error</AlertTitle>
|
||||
<AlertTitle>Errore</AlertTitle>
|
||||
<AlertDescription>{errorMessage}</AlertDescription>
|
||||
</Alert>
|
||||
</div>
|
||||
@@ -280,199 +351,382 @@ export default function GiftRegistryPage() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container max-w-4xl mx-auto px-4 py-8">
|
||||
<div className="flex flex-col items-center mb-8">
|
||||
<h1 className="text-3xl font-bold mb-2 text-center">
|
||||
🎁 Gift Registry 🎁
|
||||
</h1>
|
||||
<p className="text-muted-foreground text-center">
|
||||
Choose a gift from the wishlist to help celebrate Emma's 1st birthday
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Tabs
|
||||
defaultValue="available"
|
||||
value={activeTab}
|
||||
onValueChange={setActiveTab}
|
||||
className="w-full"
|
||||
<div
|
||||
className="min-h-screen pb-16 pt-8"
|
||||
style={{
|
||||
backgroundColor: colors.background,
|
||||
color: colors.text,
|
||||
fontFamily: fonts.body,
|
||||
}}
|
||||
>
|
||||
<motion.div
|
||||
className="container max-w-4xl mx-auto px-4"
|
||||
variants={containerVariants}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
>
|
||||
<TabsList className="grid w-full grid-cols-2 mb-6">
|
||||
<TabsTrigger value="available" className="text-base">
|
||||
Available Gifts
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="reserved" className="text-base">
|
||||
Your Reservations{" "}
|
||||
{reservedGifts.length > 0 && `(${reservedGifts.length})`}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
{/* Back to Invitation Link */}
|
||||
<motion.div variants={itemVariants} className="mb-6">
|
||||
<Link
|
||||
href={`/invite/${slug}?code=${invitationCode}`}
|
||||
className="inline-flex items-center text-sm hover:underline"
|
||||
style={{ color: colors.primary }}
|
||||
>
|
||||
← Torna all'invito
|
||||
</Link>
|
||||
</motion.div>
|
||||
|
||||
<TabsContent value="available">
|
||||
{availableGifts.length === 0 ? (
|
||||
<Alert>
|
||||
<AlertTitle>No Available Gifts</AlertTitle>
|
||||
<AlertDescription>
|
||||
All gifts have been reserved or there are no gifts available at
|
||||
this time.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
) : (
|
||||
<div className="overflow-x-auto">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Name</TableHead>
|
||||
<TableHead>Priority</TableHead>
|
||||
<TableHead>Link</TableHead>
|
||||
<TableHead>Description</TableHead>
|
||||
<TableHead></TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{availableGifts.map((gift) => {
|
||||
const priority = formatPriority(gift.priority || "medium");
|
||||
return (
|
||||
<TableRow key={gift.id}>
|
||||
<TableCell className="font-medium">
|
||||
{gift.name}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Badge variant="outline" className={priority.color}>
|
||||
{priority.label}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{gift.purchase_url ? (
|
||||
<a
|
||||
href={gift.purchase_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center text-primary hover:underline"
|
||||
>
|
||||
<ExternalLink size={14} className="mr-1" />
|
||||
View Store
|
||||
</a>
|
||||
) : (
|
||||
<span className="text-muted-foreground text-sm">
|
||||
None
|
||||
</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>{gift.description || ""}</TableCell>
|
||||
<TableCell>
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() => handleReserveClick(gift)}
|
||||
>
|
||||
<Gift className="h-4 w-4 mr-1" />
|
||||
Reserve
|
||||
</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
)}
|
||||
</TabsContent>
|
||||
<motion.div
|
||||
variants={itemVariants}
|
||||
className="flex flex-col items-center mb-8"
|
||||
>
|
||||
<h1
|
||||
className="text-4xl font-bold mb-2 text-center"
|
||||
style={{
|
||||
fontFamily: fonts.heading,
|
||||
color: colors.secondary,
|
||||
}}
|
||||
>
|
||||
Lista Regali
|
||||
</h1>
|
||||
<p className="text-center mb-2" style={{ color: colors.textLight }}>
|
||||
Scegli un regalo dalla lista per festeggiare il primo compleanno di
|
||||
Emma
|
||||
</p>
|
||||
<div
|
||||
className="w-24 h-1 rounded-full mt-2"
|
||||
style={{ backgroundColor: colors.accent }}
|
||||
></div>
|
||||
</motion.div>
|
||||
|
||||
<TabsContent value="reserved">
|
||||
{reservedGifts.length === 0 ? (
|
||||
<Alert>
|
||||
<AlertTitle>No Reservations</AlertTitle>
|
||||
<AlertDescription>
|
||||
You haven't reserved any gifts yet. Switch to the "Available
|
||||
Gifts" tab to make a selection.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
) : (
|
||||
<div className="overflow-x-auto">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Name</TableHead>
|
||||
<TableHead>Priority</TableHead>
|
||||
<TableHead>Link</TableHead>
|
||||
{/*<TableHead>Quantity</TableHead>*/}
|
||||
<TableHead>Description</TableHead>
|
||||
<TableHead></TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{reservedGifts.map((gift) => {
|
||||
const priority = formatPriority(gift.priority || "medium");
|
||||
const quantity = getReservationQuantity(gift);
|
||||
return (
|
||||
<TableRow key={gift.id}>
|
||||
<TableCell className="font-medium">
|
||||
{gift.name}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Badge variant="outline" className={priority.color}>
|
||||
{priority.label}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{gift.purchase_url ? (
|
||||
<a
|
||||
href={gift.purchase_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center text-primary hover:underline"
|
||||
>
|
||||
<ExternalLink size={14} className="mr-1" />
|
||||
View Store
|
||||
</a>
|
||||
) : (
|
||||
<span className="text-muted-foreground text-sm">
|
||||
None
|
||||
</span>
|
||||
)}
|
||||
</TableCell>
|
||||
{/*<TableCell>{quantity}</TableCell>*/}
|
||||
<TableCell>{gift.description || ""}</TableCell>
|
||||
<TableCell>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => handleRemoveReservation(gift)}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
</TableCell>
|
||||
<motion.div variants={itemVariants}>
|
||||
<Tabs
|
||||
defaultValue="available"
|
||||
value={activeTab}
|
||||
onValueChange={setActiveTab}
|
||||
className="w-full"
|
||||
>
|
||||
<TabsList
|
||||
className="grid w-full grid-cols-2 mb-6 rounded-lg p-1"
|
||||
style={{
|
||||
backgroundColor: colors.backgroundDark,
|
||||
borderColor: colors.primary,
|
||||
}}
|
||||
>
|
||||
<TabsTrigger
|
||||
value="available"
|
||||
className="text-base rounded-md data-[state=active]:shadow-sm"
|
||||
style={{
|
||||
color: colors.text,
|
||||
backgroundColor: "transparent",
|
||||
// "&[data-state=active]": {
|
||||
// backgroundColor: "white",
|
||||
// color: colors.primary,
|
||||
// },
|
||||
}}
|
||||
>
|
||||
Regali Disponibili
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="reserved"
|
||||
className="text-base rounded-md data-[state=active]:shadow-sm"
|
||||
style={{
|
||||
color: colors.text,
|
||||
backgroundColor: "transparent",
|
||||
// "&[data-state=active]": {
|
||||
// backgroundColor: "white",
|
||||
// color: colors.primary,
|
||||
// },
|
||||
}}
|
||||
>
|
||||
Le Tue Prenotazioni{" "}
|
||||
{reservedGifts.length > 0 && `(${reservedGifts.length})`}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="available">
|
||||
{availableGifts.length === 0 ? (
|
||||
<Alert
|
||||
style={{
|
||||
backgroundColor: colors.backgroundDark,
|
||||
color: colors.text,
|
||||
border: `1px solid ${colors.primary}`,
|
||||
}}
|
||||
>
|
||||
<AlertTitle style={{ color: colors.text }}>
|
||||
Nessun Regalo Disponibile
|
||||
</AlertTitle>
|
||||
<AlertDescription style={{ color: colors.textLight }}>
|
||||
Tutti i regali sono stati prenotati o non ci sono regali
|
||||
disponibili al momento.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
) : (
|
||||
<div
|
||||
className="overflow-x-auto rounded-lg border"
|
||||
style={{
|
||||
borderColor: colors.backgroundDark,
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
>
|
||||
<Table>
|
||||
<TableHeader
|
||||
style={{ backgroundColor: colors.backgroundDark }}
|
||||
>
|
||||
<TableRow>
|
||||
<TableHead style={{ color: colors.text }}>
|
||||
Nome
|
||||
</TableHead>
|
||||
<TableHead style={{ color: colors.text }}>
|
||||
Priorità
|
||||
</TableHead>
|
||||
<TableHead style={{ color: colors.text }}>
|
||||
Link
|
||||
</TableHead>
|
||||
<TableHead style={{ color: colors.text }}>
|
||||
Descrizione
|
||||
</TableHead>
|
||||
<TableHead></TableHead>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
)}
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{availableGifts.map((gift) => {
|
||||
const priority = formatPriority(
|
||||
gift.priority || "medium",
|
||||
);
|
||||
return (
|
||||
<TableRow
|
||||
key={gift.id}
|
||||
style={{ borderBottomColor: colors.backgroundDark }}
|
||||
>
|
||||
<TableCell
|
||||
className="font-medium"
|
||||
style={{ color: colors.text }}
|
||||
>
|
||||
{gift.name}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={priority.color}
|
||||
>
|
||||
{priority.label}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{gift.purchase_url ? (
|
||||
<a
|
||||
href={gift.purchase_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center hover:underline"
|
||||
style={{ color: colors.primary }}
|
||||
>
|
||||
<ExternalLink size={14} className="mr-1" />
|
||||
Vedi Negozio
|
||||
</a>
|
||||
) : (
|
||||
<span style={{ color: colors.textLight }}>
|
||||
Nessuno
|
||||
</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell style={{ color: colors.textLight }}>
|
||||
{gift.description || ""}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() => handleReserveClick(gift)}
|
||||
style={{
|
||||
backgroundColor: colors.secondary,
|
||||
color: "white",
|
||||
}}
|
||||
className="hover:opacity-90"
|
||||
>
|
||||
<Gift className="h-4 w-4 mr-1" />
|
||||
Prenota
|
||||
</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
)}
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="reserved">
|
||||
{reservedGifts.length === 0 ? (
|
||||
<Alert
|
||||
style={{
|
||||
backgroundColor: colors.backgroundDark,
|
||||
color: colors.text,
|
||||
border: `1px solid ${colors.primary}`,
|
||||
}}
|
||||
>
|
||||
<AlertTitle style={{ color: colors.text }}>
|
||||
Nessuna Prenotazione
|
||||
</AlertTitle>
|
||||
<AlertDescription style={{ color: colors.textLight }}>
|
||||
Non hai ancora prenotato alcun regalo. Passa alla scheda
|
||||
"Regali Disponibili" per fare una selezione.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
) : (
|
||||
<div
|
||||
className="overflow-x-auto rounded-lg border"
|
||||
style={{
|
||||
borderColor: colors.backgroundDark,
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
>
|
||||
<Table>
|
||||
<TableHeader
|
||||
style={{ backgroundColor: colors.backgroundDark }}
|
||||
>
|
||||
<TableRow>
|
||||
<TableHead style={{ color: colors.text }}>
|
||||
Name
|
||||
</TableHead>
|
||||
<TableHead style={{ color: colors.text }}>
|
||||
Priority
|
||||
</TableHead>
|
||||
<TableHead style={{ color: colors.text }}>
|
||||
Link
|
||||
</TableHead>
|
||||
<TableHead style={{ color: colors.text }}>
|
||||
Description
|
||||
</TableHead>
|
||||
<TableHead></TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{reservedGifts.map((gift) => {
|
||||
const priority = formatPriority(
|
||||
gift.priority || "medium",
|
||||
);
|
||||
const quantity = getReservationQuantity(gift);
|
||||
return (
|
||||
<TableRow
|
||||
key={gift.id}
|
||||
style={{ borderBottomColor: colors.backgroundDark }}
|
||||
>
|
||||
<TableCell
|
||||
className="font-medium"
|
||||
style={{ color: colors.text }}
|
||||
>
|
||||
{gift.name}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={priority.color}
|
||||
>
|
||||
{priority.label}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{gift.purchase_url ? (
|
||||
<a
|
||||
href={gift.purchase_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center hover:underline"
|
||||
style={{ color: colors.primary }}
|
||||
>
|
||||
<ExternalLink size={14} className="mr-1" />
|
||||
View Store
|
||||
</a>
|
||||
) : (
|
||||
<span style={{ color: colors.textLight }}>
|
||||
None
|
||||
</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell style={{ color: colors.textLight }}>
|
||||
{gift.description || ""}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => handleRemoveReservation(gift)}
|
||||
style={{
|
||||
borderColor: colors.primary,
|
||||
color: colors.primary,
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
className="hover:opacity-90"
|
||||
>
|
||||
Rimuovi
|
||||
</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
)}
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
{/* Reservation Dialog */}
|
||||
<Dialog open={isReserving} onOpenChange={setIsReserving}>
|
||||
<DialogContent>
|
||||
<DialogContent
|
||||
style={{
|
||||
backgroundColor: colors.background,
|
||||
borderColor: colors.primary,
|
||||
}}
|
||||
>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Reserve Gift</DialogTitle>
|
||||
<DialogDescription>
|
||||
<DialogTitle
|
||||
style={{
|
||||
color: colors.secondary,
|
||||
fontFamily: fonts.heading,
|
||||
}}
|
||||
>
|
||||
Prenota Regalo
|
||||
</DialogTitle>
|
||||
<DialogDescription style={{ color: colors.textLight }}>
|
||||
{selectedGift?.name} - {selectedGift?.description}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="py-4">
|
||||
<div className="mb-4">
|
||||
<label className="block text-sm font-medium mb-1">
|
||||
How many would you like to reserve?
|
||||
<label
|
||||
className="block text-sm font-medium mb-1"
|
||||
style={{ color: colors.text }}
|
||||
>
|
||||
Quanti ne vuoi prenotare?
|
||||
</label>
|
||||
<Select value={quantity} onValueChange={setQuantity}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select quantity" />
|
||||
<SelectTrigger
|
||||
style={{
|
||||
borderColor: colors.backgroundDark,
|
||||
color: colors.text,
|
||||
}}
|
||||
>
|
||||
<SelectValue placeholder="Seleziona quantità" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectContent
|
||||
style={{
|
||||
backgroundColor: colors.background,
|
||||
borderColor: colors.backgroundDark,
|
||||
}}
|
||||
>
|
||||
{selectedGift &&
|
||||
getQuantityOptions(selectedGift).map((num) => (
|
||||
<SelectItem key={num} value={num.toString()}>
|
||||
<SelectItem
|
||||
key={num}
|
||||
value={num.toString()}
|
||||
style={{ color: colors.text }}
|
||||
>
|
||||
{num}
|
||||
</SelectItem>
|
||||
))}
|
||||
@@ -481,27 +735,46 @@ export default function GiftRegistryPage() {
|
||||
</div>
|
||||
|
||||
{selectedGift?.purchase_url && (
|
||||
<div className="mt-4 p-3 bg-muted rounded-md text-sm">
|
||||
<p className="font-medium mb-1">Where to buy:</p>
|
||||
<div
|
||||
className="mt-4 p-3 rounded-md text-sm"
|
||||
style={{ backgroundColor: colors.backgroundDark }}
|
||||
>
|
||||
<p className="font-medium mb-1" style={{ color: colors.text }}>
|
||||
Dove acquistare:
|
||||
</p>
|
||||
<a
|
||||
href={selectedGift.purchase_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-primary inline-flex items-center hover:underline"
|
||||
className="inline-flex items-center hover:underline"
|
||||
style={{ color: colors.primary }}
|
||||
>
|
||||
<ExternalLink size={14} className="mr-1" />
|
||||
Visit Store
|
||||
Visita Negozio
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => setIsReserving(false)}>
|
||||
Cancel
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setIsReserving(false)}
|
||||
style={{
|
||||
borderColor: colors.backgroundDark,
|
||||
color: colors.text,
|
||||
}}
|
||||
>
|
||||
Annulla
|
||||
</Button>
|
||||
<Button onClick={handleConfirmReservation}>
|
||||
Confirm Reservation
|
||||
<Button
|
||||
onClick={handleConfirmReservation}
|
||||
style={{
|
||||
backgroundColor: colors.secondary,
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
Conferma Prenotazione
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
|
||||
Reference in New Issue
Block a user