dashboard/requests is blank
This commit is contained in:
parent
88576a15a2
commit
7738ad28ae
|
|
@ -0,0 +1,161 @@
|
||||||
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
|
import { ListOrdered, Check, X } from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import Image from "next/image";
|
||||||
|
import type { Toy } from "@/types";
|
||||||
|
import { mockToys } from "@/lib/mockData";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { getI18n } from "@/locales/server";
|
||||||
|
|
||||||
|
interface RentalRequest {
|
||||||
|
id: string;
|
||||||
|
toy: Toy;
|
||||||
|
requesterName: string;
|
||||||
|
requesterId: string;
|
||||||
|
requestedDates: string; // e.g., "Aug 5, 2024 - Aug 10, 2024"
|
||||||
|
status: 'pending' | 'approved' | 'declined';
|
||||||
|
message?: string;
|
||||||
|
dataAiHint?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rentalRequests: RentalRequest[] = [
|
||||||
|
{
|
||||||
|
id: 'req1',
|
||||||
|
toy: mockToys[0],
|
||||||
|
requesterName: 'Charlie Brown',
|
||||||
|
requesterId: 'user4',
|
||||||
|
requestedDates: 'August 10, 2024 - August 17, 2024',
|
||||||
|
status: 'pending',
|
||||||
|
message: 'My son would love to play with these for his birthday week!',
|
||||||
|
dataAiHint: mockToys[0]?.category.toLowerCase(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'req2',
|
||||||
|
toy: mockToys[3],
|
||||||
|
requesterName: 'Diana Prince',
|
||||||
|
requesterId: 'user5',
|
||||||
|
requestedDates: 'September 1, 2024 - September 5, 2024',
|
||||||
|
status: 'approved',
|
||||||
|
dataAiHint: mockToys[3]?.category.toLowerCase(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'req3',
|
||||||
|
toy: mockToys[0],
|
||||||
|
requesterName: 'Edward Nigma',
|
||||||
|
requesterId: 'user6',
|
||||||
|
requestedDates: 'July 20, 2024 - July 22, 2024',
|
||||||
|
status: 'declined',
|
||||||
|
message: 'Looking for a weekend rental.',
|
||||||
|
dataAiHint: mockToys[0]?.category.toLowerCase(),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const currentUserToyRequests = rentalRequests.filter(req => req.toy.ownerId === 'user1');
|
||||||
|
|
||||||
|
|
||||||
|
export default async function RentalRequestsPage() {
|
||||||
|
const t = await getI18n();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-8">
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-bold font-headline text-primary">{t('dashboard.requests.title')}</h1>
|
||||||
|
<p className="text-muted-foreground">{t('dashboard.requests.description')}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{currentUserToyRequests.length === 0 ? (
|
||||||
|
<Card className="text-center py-12 shadow-md">
|
||||||
|
<CardHeader>
|
||||||
|
<ListOrdered className="h-16 w-16 mx-auto text-muted-foreground mb-4" />
|
||||||
|
<CardTitle>{t('dashboard.requests.no_requests_title')}</CardTitle>
|
||||||
|
<CardDescription>{t('dashboard.requests.no_requests_description')}</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<p className="text-sm text-muted-foreground">{t('dashboard.requests.no_requests_content')}</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
) : (
|
||||||
|
<div className="space-y-6">
|
||||||
|
{currentUserToyRequests.map(request => (
|
||||||
|
<RequestItemCard key={request.id} request={request} t={t} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RequestItemCardProps {
|
||||||
|
request: RentalRequest;
|
||||||
|
t: (key: string) => string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function RequestItemCard({ request, t }: RequestItemCardProps) {
|
||||||
|
const placeholderHint = request.dataAiHint || request.toy.category.toLowerCase() || "toy";
|
||||||
|
|
||||||
|
const getStatusBadgeVariant = (status: RentalRequest['status']) => {
|
||||||
|
if (status === 'approved') return 'default';
|
||||||
|
if (status === 'declined') return 'destructive';
|
||||||
|
return 'secondary';
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStatusText = (status: RentalRequest['status']) => {
|
||||||
|
if (status === 'approved') return t('dashboard.requests.status_approved');
|
||||||
|
if (status === 'declined') return t('dashboard.requests.status_declined');
|
||||||
|
return t('dashboard.requests.status_pending');
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card className="overflow-hidden shadow-lg hover:shadow-xl transition-shadow duration-300">
|
||||||
|
<div className="flex flex-col md:flex-row">
|
||||||
|
<div className="md:w-1/4 lg:w-1/5 relative aspect-video md:aspect-auto">
|
||||||
|
<Image
|
||||||
|
src={request.toy.images[0] || 'https://placehold.co/200x150.png'}
|
||||||
|
alt={request.toy.name}
|
||||||
|
layout="fill"
|
||||||
|
objectFit="cover"
|
||||||
|
data-ai-hint={placeholderHint}
|
||||||
|
className="md:rounded-l-lg md:rounded-tr-none rounded-t-lg"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex-1 p-6">
|
||||||
|
<div className="flex justify-between items-start mb-2">
|
||||||
|
<CardTitle className="text-xl font-headline">{request.toy.name}</CardTitle>
|
||||||
|
<Badge variant={getStatusBadgeVariant(request.status)}>{getStatusText(request.status)}</Badge>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
{t('dashboard.requests.requested_by')}: <span className="font-medium text-foreground">{request.requesterName}</span>
|
||||||
|
</p>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
{t('dashboard.requests.dates')}: <span className="font-medium text-foreground">{request.requestedDates}</span>
|
||||||
|
</p>
|
||||||
|
{request.message && (
|
||||||
|
<p className="text-sm text-muted-foreground mt-2 bg-muted/50 p-2 rounded-md">
|
||||||
|
<span className="font-medium text-foreground">{t('dashboard.requests.message')}:</span> "{request.message}"
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{request.status === 'pending' && (
|
||||||
|
<div className="mt-4 flex space-x-3">
|
||||||
|
<Button size="sm" className="bg-green-600 hover:bg-green-700">
|
||||||
|
<Check className="mr-1 h-4 w-4" /> {t('dashboard.requests.approve_button')}
|
||||||
|
</Button>
|
||||||
|
<Button variant="destructive" size="sm">
|
||||||
|
<X className="mr-1 h-4 w-4" /> {t('dashboard.requests.decline_button')}
|
||||||
|
</Button>
|
||||||
|
<Button variant="outline" size="sm">{t('dashboard.requests.message_requester_button')}</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{request.status !== 'pending' && (
|
||||||
|
<div className="mt-4">
|
||||||
|
<Link href={`/dashboard/my-toys/edit/${request.toy.id}`} passHref>
|
||||||
|
<Button variant="link" size="sm" className="p-0 h-auto">{t('dashboard.requests.view_toy_listing_button')}</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -129,4 +129,19 @@ export default {
|
||||||
'dashboard.rentals.rental_ends': 'Rental ends: {date}',
|
'dashboard.rentals.rental_ends': 'Rental ends: {date}',
|
||||||
'dashboard.rentals.view_toy_details_button': 'View Toy Details',
|
'dashboard.rentals.view_toy_details_button': 'View Toy Details',
|
||||||
'dashboard.rentals.contact_owner_button': 'Contact Owner',
|
'dashboard.rentals.contact_owner_button': 'Contact Owner',
|
||||||
|
'dashboard.requests.title': 'Rental Requests',
|
||||||
|
'dashboard.requests.description': 'Manage incoming rental requests for your toys.',
|
||||||
|
'dashboard.requests.no_requests_title': 'No Rental Requests',
|
||||||
|
'dashboard.requests.no_requests_description': 'You currently have no pending rental requests for your toys.',
|
||||||
|
'dashboard.requests.no_requests_content': 'When someone requests to rent one of your toys, it will appear here.',
|
||||||
|
'dashboard.requests.requested_by': 'Requested by',
|
||||||
|
'dashboard.requests.dates': 'Dates',
|
||||||
|
'dashboard.requests.message': 'Message',
|
||||||
|
'dashboard.requests.approve_button': 'Approve',
|
||||||
|
'dashboard.requests.decline_button': 'Decline',
|
||||||
|
'dashboard.requests.message_requester_button': 'Message Requester',
|
||||||
|
'dashboard.requests.view_toy_listing_button': 'View Toy Listing',
|
||||||
|
'dashboard.requests.status_pending': 'Pending',
|
||||||
|
'dashboard.requests.status_approved': 'Approved',
|
||||||
|
'dashboard.requests.status_declined': 'Declined',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
||||||
|
|
@ -129,4 +129,19 @@ export default {
|
||||||
'dashboard.rentals.rental_ends': '租借結束於:{date}',
|
'dashboard.rentals.rental_ends': '租借結束於:{date}',
|
||||||
'dashboard.rentals.view_toy_details_button': '查看玩具詳情',
|
'dashboard.rentals.view_toy_details_button': '查看玩具詳情',
|
||||||
'dashboard.rentals.contact_owner_button': '聯絡擁有者',
|
'dashboard.rentals.contact_owner_button': '聯絡擁有者',
|
||||||
|
'dashboard.requests.title': '租借請求',
|
||||||
|
'dashboard.requests.description': '管理您玩具的租借請求。',
|
||||||
|
'dashboard.requests.no_requests_title': '沒有租借請求',
|
||||||
|
'dashboard.requests.no_requests_description': '您目前沒有任何待處理的玩具租借請求。',
|
||||||
|
'dashboard.requests.no_requests_content': '當有人請求租借您的玩具時,請求將會出現在這裡。',
|
||||||
|
'dashboard.requests.requested_by': '請求者',
|
||||||
|
'dashboard.requests.dates': '日期',
|
||||||
|
'dashboard.requests.message': '訊息',
|
||||||
|
'dashboard.requests.approve_button': '批准',
|
||||||
|
'dashboard.requests.decline_button': '拒絕',
|
||||||
|
'dashboard.requests.message_requester_button': '傳訊息給請求者',
|
||||||
|
'dashboard.requests.view_toy_listing_button': '查看玩具列表',
|
||||||
|
'dashboard.requests.status_pending': '待處理',
|
||||||
|
'dashboard.requests.status_approved': '已批准',
|
||||||
|
'dashboard.requests.status_declined': '已拒絕',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue