Add purchase link and reservation details to gift list
Enhanced the gift list by showing a clickable purchase link icon and added conditional reservation details for reserved or received items using a popover. Simplified and cleaned up related code for better readability and maintainability.
This commit is contained in:
@@ -6,16 +6,15 @@ import React, { useEffect, useState } from "react";
|
|||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import {
|
import {
|
||||||
ChevronRight,
|
|
||||||
Loader2,
|
|
||||||
AlertTriangle,
|
AlertTriangle,
|
||||||
|
ChevronRight,
|
||||||
|
Edit,
|
||||||
|
ExternalLink,
|
||||||
|
Loader2,
|
||||||
|
MoreHorizontal,
|
||||||
Plus,
|
Plus,
|
||||||
Search,
|
Search,
|
||||||
Filter,
|
|
||||||
Edit,
|
|
||||||
Trash,
|
Trash,
|
||||||
MoreHorizontal,
|
|
||||||
Settings,
|
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useEvents } from "@/context/event-context";
|
import { useEvents } from "@/context/event-context";
|
||||||
import { useGifts } from "@/context/gift-context";
|
import { useGifts } from "@/context/gift-context";
|
||||||
@@ -45,9 +44,14 @@ import {
|
|||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { GiftStatus, GiftPriority } from "@/client/types.gen";
|
import { GiftPriority, GiftStatus } from "@/client/types.gen";
|
||||||
import { CategoryModal } from "@/components/gifts/category-modal";
|
import { CategoryModal } from "@/components/gifts/category-modal";
|
||||||
import { GiftModal } from "@/components/gifts/gift-modal";
|
import { GiftModal } from "@/components/gifts/gift-modal";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
|
|
||||||
export default function GiftRegistryPage() {
|
export default function GiftRegistryPage() {
|
||||||
const { slug } = useParams<{ slug: string }>();
|
const { slug } = useParams<{ slug: string }>();
|
||||||
@@ -57,6 +61,7 @@ export default function GiftRegistryPage() {
|
|||||||
items,
|
items,
|
||||||
isLoadingCategories,
|
isLoadingCategories,
|
||||||
isLoadingItems,
|
isLoadingItems,
|
||||||
|
purchases,
|
||||||
error,
|
error,
|
||||||
refetchCategories,
|
refetchCategories,
|
||||||
refetchItems,
|
refetchItems,
|
||||||
@@ -387,19 +392,70 @@ export default function GiftRegistryPage() {
|
|||||||
const category = categories?.find(
|
const category = categories?.find(
|
||||||
(c) => c.id === item.category_id,
|
(c) => c.id === item.category_id,
|
||||||
);
|
);
|
||||||
|
const canShowReservations = item.status
|
||||||
|
? (
|
||||||
|
[
|
||||||
|
GiftStatus.RESERVED,
|
||||||
|
GiftStatus.RECEIVED,
|
||||||
|
] as GiftStatus[]
|
||||||
|
).includes(item.status)
|
||||||
|
: false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment key={item.id}>
|
<React.Fragment key={item.id}>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
{category?.name || "Uncategorized"}
|
{category?.name || "Uncategorized"}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="font-medium">
|
|
||||||
|
<TableCell className="flex items-center gap-2 font-medium">
|
||||||
|
{/* Purchase URL clickable icon */}
|
||||||
|
{item.purchase_url ? (
|
||||||
|
<Link
|
||||||
|
href={item.purchase_url}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<ExternalLink className="w-4 h-4 text-blue-500 hover:text-blue-600" />
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<ExternalLink className="w-4 h-4 text-gray-300 cursor-not-allowed" />
|
||||||
|
)}
|
||||||
{item.name}
|
{item.name}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<TableCell>{item.quantity_requested || 1}</TableCell>
|
<TableCell>{item.quantity_requested || 1}</TableCell>
|
||||||
<TableCell>{item.formatted_price || "-"}</TableCell>
|
<TableCell>{item.formatted_price || "-"}</TableCell>
|
||||||
<TableCell>{getPriorityBadge(item.priority)}</TableCell>
|
<TableCell>{getPriorityBadge(item.priority)}</TableCell>
|
||||||
<TableCell>{getStatusBadge(item.status)}</TableCell>
|
|
||||||
|
<TableCell>
|
||||||
|
{canShowReservations ? (
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<div className="cursor-pointer">
|
||||||
|
{getStatusBadge(item.status)}
|
||||||
|
</div>
|
||||||
|
</PopoverTrigger>
|
||||||
|
{/*<PopoverContent className="text-sm">*/}
|
||||||
|
{/* {item.reservations &&*/}
|
||||||
|
{/* item.reservations.length > 0 ? (*/}
|
||||||
|
{/* <ul className="list-disc">*/}
|
||||||
|
{/* {item.reservations.map((res) => (*/}
|
||||||
|
{/* <li key={res.guest_id}>*/}
|
||||||
|
{/* {res.guest_name}: {res.quantity}*/}
|
||||||
|
{/* </li>*/}
|
||||||
|
{/* ))}*/}
|
||||||
|
{/* </ul>*/}
|
||||||
|
{/* ) : (*/}
|
||||||
|
{/* <p>No reservations available.</p>*/}
|
||||||
|
{/* )}*/}
|
||||||
|
{/*</PopoverContent>*/}
|
||||||
|
</Popover>
|
||||||
|
) : (
|
||||||
|
getStatusBadge(item.status)
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
|
||||||
<TableCell className="text-right">
|
<TableCell className="text-right">
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
@@ -428,68 +484,18 @@ export default function GiftRegistryPage() {
|
|||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
|
||||||
|
{/* Separate row for description */}
|
||||||
|
{/*{item.description && (*/}
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell
|
<TableCell
|
||||||
colSpan={7}
|
colSpan={7}
|
||||||
className="py-1 px-4 border-t-0 bg-gray-50 dark:bg-gray-800/50 text-sm text-gray-500 dark:text-gray-400"
|
className="py-1 px-4 bg-gray-50 dark:bg-gray-800/50 text-sm text-gray-500 dark:text-gray-400 h-8"
|
||||||
>
|
>
|
||||||
<div className="flex flex-col gap-1">
|
{item.description}
|
||||||
{/* Description - show if available */}
|
|
||||||
{item.description && <p>{item.description}</p>}
|
|
||||||
|
|
||||||
{/* Status-specific information */}
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
{item.status === GiftStatus.AVAILABLE && (
|
|
||||||
<>
|
|
||||||
{item.store_name && (
|
|
||||||
<span>Store: {item.store_name}</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{item.purchase_url && (
|
|
||||||
<>
|
|
||||||
{item.store_name && <span>•</span>}
|
|
||||||
<a
|
|
||||||
href={item.purchase_url}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="text-blue-600 hover:underline"
|
|
||||||
>
|
|
||||||
Shop Link
|
|
||||||
</a>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!item.store_name &&
|
|
||||||
!item.purchase_url &&
|
|
||||||
item.brand && (
|
|
||||||
<span>Brand: {item.brand}</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!item.store_name &&
|
|
||||||
!item.purchase_url &&
|
|
||||||
!item.brand && (
|
|
||||||
<span className={"italic"}>
|
|
||||||
No purchase information available
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{item.status === GiftStatus.RESERVED && (
|
|
||||||
<span>Reserved</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{item.status === GiftStatus.PURCHASED && (
|
|
||||||
<span>Purchased</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{item.status === GiftStatus.RECEIVED && (
|
|
||||||
<span>Received</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
{/*)}*/}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user