Skip to content

Commit 96c0285

Browse files
authored
Issue, Created announcment coming over sidebar (#448)
1 parent 9cb78c5 commit 96c0285

2 files changed

Lines changed: 37 additions & 196 deletions

File tree

Lines changed: 3 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -1,175 +1,5 @@
1-
"use client";
1+
import NoticeBoardView from "@/components/Admin/NoticeBoardView";
22

3-
import { useEffect, useState } from "react";
4-
5-
interface NotificationItem {
6-
id?: string;
7-
announcelogo: string;
8-
heading: string;
9-
info: string;
10-
createdAt?: string;
11-
clubname?: string;
12-
}
13-
14-
export default function NoticeBoardView(): JSX.Element {
15-
const [notifications, setNotifications] = useState<NotificationItem[]>([]);
16-
const [selectedImage, setSelectedImage] = useState<string | null>(null);
17-
const [loading, setLoading] = useState(true);
18-
const [error, setError] = useState("");
19-
20-
useEffect(() => {
21-
const fetchAnnouncements = async () => {
22-
try {
23-
setLoading(true);
24-
setError("");
25-
26-
const response = await fetch(
27-
`${process.env.NEXT_PUBLIC_BACKEND_URL}/api/v1/notification`,
28-
{
29-
method: "GET",
30-
cache: "no-store",
31-
}
32-
);
33-
34-
const data = await response.json();
35-
36-
if (!response.ok) {
37-
throw new Error(
38-
data.message || "Failed to fetch announcements."
39-
);
40-
}
41-
42-
if (Array.isArray(data)) {
43-
setNotifications([...data].reverse());
44-
} else if (Array.isArray(data.data)) {
45-
setNotifications([...data.data].reverse());
46-
} else {
47-
setNotifications([]);
48-
}
49-
} catch (err: any) {
50-
setError(
51-
err?.message || "Something went wrong while loading announcements."
52-
);
53-
} finally {
54-
setLoading(false);
55-
}
56-
};
57-
58-
fetchAnnouncements();
59-
}, []);
60-
61-
if (loading) {
62-
return (
63-
<div className="min-h-screen bg-slate-50 flex items-center justify-center px-4">
64-
<p className="text-slate-600 text-lg">Loading announcements...</p>
65-
</div>
66-
);
67-
}
68-
69-
if (error) {
70-
return (
71-
<div className="min-h-screen bg-slate-50 flex items-center justify-center px-4">
72-
<div className="max-w-md rounded-xl border border-red-200 bg-red-50 p-6 text-center">
73-
<p className="text-red-600 font-medium">{error}</p>
74-
</div>
75-
</div>
76-
);
77-
}
78-
79-
return (
80-
<>
81-
<div className="min-h-screen bg-slate-50 px-4 py-10">
82-
<div className="mx-auto max-w-5xl">
83-
<div className="mb-10 text-center">
84-
<h1 className="text-4xl font-bold text-slate-900">
85-
Announcements
86-
</h1>
87-
<p className="mt-2 text-slate-500">
88-
Stay updated with the latest notices and updates.
89-
</p>
90-
</div>
91-
92-
{notifications.length === 0 ? (
93-
<div className="rounded-2xl border border-slate-200 bg-white p-12 text-center shadow-sm">
94-
<p className="text-lg font-medium text-slate-600">
95-
No announcements available.
96-
</p>
97-
</div>
98-
) : (
99-
<div className="space-y-6">
100-
{notifications.map((item, index) => (
101-
<div
102-
key={item.id || index}
103-
className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm hover:shadow-md transition"
104-
>
105-
<div className="flex flex-col gap-6 md:flex-row md:items-start md:justify-between">
106-
<div className="flex-1">
107-
{item.clubname && (
108-
<p className="mb-2 text-sm font-semibold uppercase tracking-wide text-blue-700">
109-
{item.clubname}
110-
</p>
111-
)}
112-
113-
<h2 className="text-2xl font-semibold text-slate-900">
114-
{item.heading}
115-
</h2>
116-
117-
<p className="mt-4 whitespace-pre-line text-slate-700 leading-7">
118-
{item.info}
119-
</p>
120-
121-
{item.createdAt && (
122-
<p className="mt-4 text-sm text-slate-400">
123-
{new Date(item.createdAt).toLocaleString()}
124-
</p>
125-
)}
126-
</div>
127-
128-
{item.announcelogo && (
129-
<div className="md:w-32 flex-shrink-0">
130-
<img
131-
src={item.announcelogo}
132-
alt="Announcement logo"
133-
onClick={() =>
134-
setSelectedImage(item.announcelogo)
135-
}
136-
className="h-24 w-24 rounded-xl border border-slate-200 object-cover cursor-pointer hover:scale-105 transition"
137-
/>
138-
</div>
139-
)}
140-
</div>
141-
</div>
142-
))}
143-
</div>
144-
)}
145-
</div>
146-
</div>
147-
148-
{selectedImage && (
149-
<div
150-
className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 px-4"
151-
onClick={() => setSelectedImage(null)}
152-
>
153-
<div
154-
className="relative"
155-
onClick={(e) => e.stopPropagation()}
156-
>
157-
<button
158-
type="button"
159-
onClick={() => setSelectedImage(null)}
160-
className="absolute -top-12 right-0 text-white text-4xl font-bold"
161-
>
162-
×
163-
</button>
164-
165-
<img
166-
src={selectedImage}
167-
alt="Announcement preview"
168-
className="max-h-[85vh] max-w-[90vw] rounded-xl shadow-2xl"
169-
/>
170-
</div>
171-
</div>
172-
)}
173-
</>
174-
);
3+
export default function Page() {
4+
return <NoticeBoardView />;
1755
}

src/components/Admin/NoticeBoardView.tsx

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import { useEffect, useState } from "react";
44

55
interface NotificationItem {
66
id?: string;
7-
clubname?: string;
7+
announcelogo: string;
88
heading: string;
99
info: string;
10-
announcelogo: string;
1110
createdAt?: string;
11+
clubname?: string;
1212
}
1313

1414
export default function NoticeBoardView(): JSX.Element {
@@ -31,26 +31,37 @@ export default function NoticeBoardView(): JSX.Element {
3131
}
3232
);
3333

34-
const result = await response.json();
34+
const data = await response.json();
3535

3636
if (!response.ok) {
3737
throw new Error(
38-
result.message || "Failed to load announcements."
38+
data.message || "Failed to fetch announcements."
3939
);
4040
}
4141

42-
let announcements: NotificationItem[] = [];
43-
44-
if (Array.isArray(result)) {
45-
announcements = result;
46-
} else if (Array.isArray(result.data)) {
47-
announcements = result.data;
42+
// Latest announcement first
43+
if (Array.isArray(data)) {
44+
setNotifications(
45+
[...data].sort(
46+
(a, b) =>
47+
new Date(b.createdAt || "").getTime() -
48+
new Date(a.createdAt || "").getTime()
49+
)
50+
);
51+
} else if (Array.isArray(data.data)) {
52+
setNotifications(
53+
[...data.data].sort(
54+
(a, b) =>
55+
new Date(b.createdAt || "").getTime() -
56+
new Date(a.createdAt || "").getTime()
57+
)
58+
);
59+
} else {
60+
setNotifications([]);
4861
}
49-
50-
setNotifications([...announcements].reverse());
51-
} catch (error: any) {
62+
} catch (err: any) {
5263
setError(
53-
error?.message ||
64+
err?.message ||
5465
"Something went wrong while loading announcements."
5566
);
5667
} finally {
@@ -63,8 +74,8 @@ export default function NoticeBoardView(): JSX.Element {
6374

6475
if (loading) {
6576
return (
66-
<div className="min-h-screen bg-slate-50 flex items-center justify-center px-4">
67-
<p className="text-lg text-slate-600">
77+
<div className="w-full bg-slate-50 flex items-center justify-center p-6">
78+
<p className="text-slate-600 text-lg">
6879
Loading announcements...
6980
</p>
7081
</div>
@@ -73,18 +84,18 @@ export default function NoticeBoardView(): JSX.Element {
7384

7485
if (error) {
7586
return (
76-
<div className="min-h-screen bg-slate-50 flex items-center justify-center px-4">
87+
<div className="w-full bg-slate-50 flex items-center justify-center p-6">
7788
<div className="max-w-md rounded-xl border border-red-200 bg-red-50 p-6 text-center">
78-
<p className="font-medium text-red-600">{error}</p>
89+
<p className="text-red-600 font-medium">{error}</p>
7990
</div>
8091
</div>
8192
);
8293
}
8394

8495
return (
8596
<>
86-
<div className="min-h-screen bg-slate-50 px-4 py-10">
87-
<div className="mx-auto max-w-5xl">
97+
<div className="w-full bg-slate-50 p-6 overflow-x-hidden">
98+
<div className="mx-auto w-full max-w-4xl">
8899
<div className="mb-10 text-center">
89100
<h1 className="text-4xl font-bold text-slate-900">
90101
Announcements
@@ -133,7 +144,7 @@ export default function NoticeBoardView(): JSX.Element {
133144
</div>
134145

135146
{item.announcelogo && (
136-
<div className="flex-shrink-0">
147+
<div className="md:w-32 flex-shrink-0">
137148
<img
138149
src={item.announcelogo}
139150
alt="Announcement logo"
@@ -142,7 +153,7 @@ export default function NoticeBoardView(): JSX.Element {
142153
item.announcelogo
143154
)
144155
}
145-
className="h-24 w-24 cursor-pointer rounded-xl border border-slate-200 object-cover hover:scale-105 transition"
156+
className="h-24 w-24 rounded-xl border border-slate-200 object-cover cursor-pointer hover:scale-105 transition"
146157
/>
147158
</div>
148159
)}
@@ -166,7 +177,7 @@ export default function NoticeBoardView(): JSX.Element {
166177
<button
167178
type="button"
168179
onClick={() => setSelectedImage(null)}
169-
className="absolute -top-12 right-0 text-4xl font-bold text-white"
180+
className="absolute -top-12 right-0 text-white text-4xl font-bold"
170181
>
171182
×
172183
</button>

0 commit comments

Comments
 (0)