Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/coming-soon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
83 changes: 83 additions & 0 deletions src/app/dashboard/components/notification-detail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"use client";

import { Button } from "@/components/ui/button";
import { ArrowLeft, Trash2 } from "lucide-react";
import Image from "next/image";

interface NotificationDetailProps {
notification: {
id: number;
title: string;
time: string;
date: string;
};
onBack: () => void;
onDelete: (id: number) => void;
}

export default function NotificationDetail({
notification,
onBack,
onDelete,
}: NotificationDetailProps) {
return (
<main className="fixed inset-0 z-50 flex items-center justify-center">
<div className="absolute inset-0 bg-black/50 backdrop-blur-sm" />
<div className="w-full md:w-[642px] mx-auto bg-[#FFFFFF] rounded-[8px] p-4 z-10">
<div className="flex items-center justify-between mb-6">
<Button
variant="ghost"
size="sm"
onClick={onBack}
className="h-8 w-8 p-0 hover:bg-gray-100"
>
<ArrowLeft className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="sm"
onClick={() => onDelete(notification.id)}
className="h-8 w-8 p-0 hover:bg-gray-100"
>
<Trash2 className="h-4 w-4" />
</Button>
</div>

<div className="space-y-4">
<div className="text-center space-y-2">
<h1 className="text-[24px] font-semibold text-[#454545]">
New Update for Writers
</h1>
<p className="text-sm text-[#454545] text-[16px]">
Step up your writing with our latest update
</p>
</div>

<div className="md:w-[300px] w-full mx-auto">
<Image
src="/coming-soon.png"
alt="Notification Banner"
width={100}
height={100}
className="w-full"
/>
</div>

<div className="text-center">
<p className="text-sm text-[#454545] text-[16px] leading-relaxed">
Compete against players worldwide, climb the global rankings, and
prove your skills. Test your strategy, outmaneuver your opponents,
and claim your place at the top. Glory awaits!
</p>
</div>

<div className="text-center pt-4">
<p className="text-xs text-[#888888] text-[16px]">
Sent: {notification.date} {notification.time}
</p>
</div>
</div>
</div>
</main>
);
}
172 changes: 166 additions & 6 deletions src/app/dashboard/notifications/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,171 @@
"use client";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { ChevronDown, Check } from "lucide-react";
import Avatar from "@mui/material/Avatar";
import { useState } from "react";
import NotificationDetail from "../components/notification-detail";

export default function Component() {
const notifications = [
{
id: 1,
title: "New updates for Writers",
time: "12:16 PM",
isNew: true,
date: "Today",
},
{
id: 2,
title: "New updates for Writers",
time: "12:19 PM",
isNew: true,
date: "Today",
},
{
id: 3,
title: "New updates for Writers",
time: "12:16 PM",
isNew: true,
date: "Yesterday",
},
{
id: 4,
title: "New updates for Writers",
time: "12:19 PM",
isNew: true,
date: "Yesterday",
},
{
id: 5,
title: "New updates for Writers",
time: "12:25 PM",
isNew: true,
date: "Yesterday",
},
{
id: 6,
title: "New updates for Writers",
time: "12:19 PM",
isNew: true,
date: "12 April, 2025",
},
];

const [selectedNotification, setSelectedNotification] = useState<
(typeof notifications)[0] | null
>(null);

const handleViewDetails = (notification: (typeof notifications)[0]) => {
setSelectedNotification(notification);
};

const handleBack = () => {
setSelectedNotification(null);
};

const handleDelete = (id: number) => {
console.log("Delete notification:", id);
setSelectedNotification(null);
};

const groupedNotifications = notifications.reduce((acc, notification) => {
if (!acc[notification.date]) {
acc[notification.date] = [];
}
acc[notification.date].push(notification);
return acc;
}, {} as Record<string, typeof notifications>);

function NotificationsPage() {
return (
<div>
<h1>Notifications</h1>
<p>This is the notifications page.</p>
</div>
<main className="w-full relative p-6 pr-10">
<div className=" bg-[#FFFFFF] p-4 rounded-[8px] w-full mx-auto shadow-md">
<div className="flex items-center justify-between mb-6">
<div className="flex items-center gap-2">
<h2 className="text-sm font-medium text-gray-900">
All Notifications (7)
</h2>
</div>
<div className="flex items-center gap-3">
<Button
variant="ghost"
size="sm"
className="text-xs text-gray-500 h-auto p-0"
>
Filter by
<ChevronDown className="ml-1 h-3 w-3" />
</Button>
<Button
variant="ghost"
size="sm"
className="text-xs text-blue-600 h-auto p-0 hover:text-blue-700"
>
<Check className="mr-1 h-3 w-3" />
Mark all as read
</Button>
</div>
</div>

<div className="space-y-4">
{Object.entries(groupedNotifications).map(([date, notifications]) => (
<div key={date}>
<div className="bg-[#F6F6F6] px-4 pt-3 mb-3 flex items-center rounded-sm">
<h3 className="text-xs font-medium text-gray-500 mb-3">
{date}
</h3>
</div>
<div className="space-y-3">
{notifications.map((notification) => (
<div
key={notification.id}
className="flex items-center gap-3"
>
<Avatar className="flex justify-center items-center h-8 w-8 bg-gray-200">
W
</Avatar>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2 mb-1">
<span className="text-sm font-medium text-gray-900">
{notification.title}
</span>
{notification.isNew && (
<Badge
variant="secondary"
className="text-xs px-2 py-0.5 bg-red-100 text-red-700 hover:bg-red-100"
>
New
</Badge>
)}
</div>
<p className="text-xs text-gray-500">
{notification.time}
</p>
</div>
<Button
variant="ghost"
size="sm"
className="text-xs text-blue-600 h-auto p-0 hover:text-blue-700"
onClick={() => handleViewDetails(notification)}
>
View Details
</Button>
</div>
))}
</div>
</div>
))}
</div>
</div>
{selectedNotification && (
<div className="absolute inset-0 bg-white">
<NotificationDetail
notification={selectedNotification}
onBack={handleBack}
onDelete={handleDelete}
/>
</div>
)}
</main>
);
}
export default NotificationsPage;
Loading