Skip to content

Commit eca3021

Browse files
explore
1 parent 678aa17 commit eca3021

23 files changed

+1477
-111
lines changed

v2/package-lock.json

+564
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

v2/package.json

+3
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,20 @@
1111
"dependencies": {
1212
"@hookform/resolvers": "^3.3.4",
1313
"@radix-ui/react-label": "^2.0.2",
14+
"@radix-ui/react-popover": "^1.0.7",
1415
"@radix-ui/react-slot": "^1.0.2",
1516
"axios": "^1.6.7",
1617
"class-variance-authority": "^0.7.0",
1718
"clsx": "^2.1.0",
19+
"date-fns": "^3.3.1",
1820
"iconsax-react": "^0.0.8",
1921
"jwt-decode": "^4.0.0",
2022
"lucide-react": "^0.335.0",
2123
"next": "14.1.0",
2224
"next-auth": "^5.0.0-beta.13",
2325
"prettier": "^3.2.5",
2426
"react": "^18",
27+
"react-day-picker": "^8.10.0",
2528
"react-dom": "^18",
2629
"react-hook-form": "^7.50.1",
2730
"react-icons": "^5.0.1",

v2/public/arrow.svg

+27
Loading

v2/src/actions/expore.ts

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
'use server';
2+
3+
import Calls from './calls';
4+
5+
const BaseUrl = process.env.BASEURL ?? 'https://evento-qo6d.onrender.com/api/v1';
6+
7+
const $http = Calls(BaseUrl);
8+
9+
export const allevent = async () => {
10+
try {
11+
const res = await $http.get('/events');
12+
if (res.status === 200) {
13+
return {
14+
status: 'success',
15+
events: res.data.data,
16+
};
17+
}
18+
} catch (e: any) {
19+
console.log(e);
20+
if (e?.response?.status === 403) {
21+
return {
22+
error: 'Forbidden',
23+
};
24+
} else if (e?.response?.status === 404) {
25+
return {
26+
error: 'Not Found. The requested endpoint was not found.',
27+
};
28+
} else {
29+
return {
30+
error: 'An error occurred. Please try again later.',
31+
};
32+
}
33+
}
34+
};
35+
36+
export const allcategories = async () => {
37+
try {
38+
const res = await $http.get('/categories');
39+
if (res.status === 200) {
40+
return {
41+
status: 'success',
42+
categories: res.data.data,
43+
};
44+
}
45+
} catch (e: any) {
46+
console.log(e);
47+
if (e?.response?.status === 403) {
48+
return {
49+
error: 'Forbidden',
50+
};
51+
} else if (e?.response?.status === 404) {
52+
return {
53+
error: 'Not Found. The requested endpoint was not found.',
54+
};
55+
} else {
56+
return {
57+
error: 'An error occurred. Please try again later.',
58+
};
59+
}
60+
}
61+
};
62+
63+
export const geteventsbycategories = async (categoryID: string) => {
64+
try {
65+
const res = await $http.get(`/categories/${categoryID}/events`);
66+
if (res.status === 200) {
67+
return {
68+
status: 'success',
69+
events: res.data.data,
70+
};
71+
}
72+
} catch (e: any) {
73+
console.log(e);
74+
if (e?.response?.status === 403) {
75+
return {
76+
error: 'Forbidden',
77+
};
78+
} else if (e?.response?.status === 404) {
79+
return {
80+
error: 'Not Found. The requested endpoint was not found.',
81+
};
82+
} else {
83+
return {
84+
error: 'An error occurred. Please try again later.',
85+
};
86+
}
87+
}
88+
};

v2/src/actions/notifications.ts

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'use server';
2+
3+
import Calls from './calls';
4+
import { cookies } from 'next/headers';
5+
6+
const BaseUrl = process.env.BASEURL ?? 'https://evento-qo6d.onrender.com/api/v1';
7+
8+
const $http = Calls(BaseUrl, true);
9+
10+
export const getNotifications = async () => {
11+
const userId = cookies()?.get('userId')?.value;
12+
13+
if (!userId) {
14+
return {
15+
error: 'Unauthorized. Missing access token.',
16+
status: 401,
17+
};
18+
}
19+
try {
20+
const res = await $http.get(`/notifications/${userId}`);
21+
if (res.status === 200) {
22+
return {
23+
status: 'success',
24+
notifications: res.data.data,
25+
};
26+
}
27+
} catch (e: any) {
28+
console.log(e);
29+
if (e?.response?.status === 401) {
30+
return {
31+
error: 'Unauthorized. Please check your access token.',
32+
status: 401,
33+
};
34+
} else if (e?.response?.status === 403) {
35+
return {
36+
error: 'Forbidden',
37+
};
38+
} else if (e?.response?.status === 404) {
39+
return {
40+
error: 'Not Found. The requested endpoint was not found.',
41+
};
42+
} else {
43+
return {
44+
error: 'An error occurred. Please try again later.',
45+
};
46+
}
47+
}
48+
};

v2/src/app/(home)/explore/page.tsx

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react';
2+
import Hero from '@/modules/explore/Hero';
3+
import Categories from '@/modules/explore/Categories';
4+
import EventsGrid from '@/modules/explore/EventsGrid';
5+
6+
const Explore = () => {
7+
return (
8+
<>
9+
<Hero />
10+
<Categories />
11+
<EventsGrid />
12+
</>
13+
);
14+
};
15+
16+
export default Explore;

v2/src/app/layout.tsx

+7-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Theme from '@/components/ThemeButton';
77
import StateCtxProvider from '@/context/StateCtx';
88
import { SessionProvider } from 'next-auth/react';
99
import UserContextProvider from '@/context/UserCtx';
10+
import ExploreContextProvider from '@/context/ExploreCtx';
1011

1112
export const metadata: Metadata = {
1213
title: 'Evento',
@@ -27,10 +28,12 @@ export default function RootLayout({
2728
<SessionProvider>
2829
<UserContextProvider>
2930
<StateCtxProvider>
30-
<AuthContextProvider>
31-
{children}
32-
<Theme />
33-
</AuthContextProvider>
31+
<ExploreContextProvider>
32+
<AuthContextProvider>
33+
{children}
34+
<Theme />
35+
</AuthContextProvider>
36+
</ExploreContextProvider>
3437
</StateCtxProvider>
3538
</UserContextProvider>
3639
</SessionProvider>
+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
'use client';
2+
3+
import Link from 'next/link';
4+
import Image from 'next/image';
5+
import React, { useState } from 'react';
6+
import { EventProps } from '@/types';
7+
import { useUserCtx } from '@/context/UserCtx';
8+
import { Location, Timer1 } from 'iconsax-react';
9+
import { convertUTCtoLocalTime } from '@/utils';
10+
import { useExploreCtx } from '@/context/ExploreCtx';
11+
12+
const ExploreCard = ({
13+
imageURL,
14+
eventID,
15+
startDate,
16+
organizerID,
17+
tickets,
18+
participants,
19+
location,
20+
title,
21+
}: EventProps) => {
22+
const [weekday, monthDay] = convertUTCtoLocalTime(startDate!);
23+
const [, , , time] = convertUTCtoLocalTime(startDate!);
24+
const { eventsSearchTerm } = useExploreCtx();
25+
const { user } = useUserCtx();
26+
27+
return (
28+
<>
29+
<Link
30+
href={organizerID === user.userID ? `/event-management/?eventid=${eventID}` : `/event/?eventid=${eventID}`}
31+
className="block border border-Grey-G80/50 dark:border-dark-two card-shadow rounded-lg hover:scale-[1.01]"
32+
>
33+
<div className="relative w-full h-[180px] rounded-t-lg overflow-hidden">
34+
<Image src={imageURL!} fill alt="Event Image" className="object-cover" />
35+
</div>
36+
<div className="p-4">
37+
<div className="flex justify-between items-center mb-1 font-nunito">
38+
<span className="font-bold text-sm text-primary-100 dark:text-dark-two ">
39+
{weekday}, {monthDay}
40+
</span>
41+
{tickets?.map((ticket) => (
42+
<div key={ticket.ticketID}>
43+
<span className="text-primary-100 bg-secondary-100 dark:bg-dark-two dark:text-dark-one rounded block px-3 py-1 capitalize">
44+
{ticket.ticketType === 'Free' ? 'Free' : `$${ticket.ticketPrice}`}
45+
</span>
46+
</div>
47+
))}
48+
</div>
49+
<h2 className="text-Grey-G800 dark:text-dark-two text-lg whitespace-nowrap overflow-hidden text-ellipsis sm:text-xl font-bold pt-1 pb-2 font-montserrat">
50+
{/* {title!} */}
51+
<strong>
52+
<span
53+
dangerouslySetInnerHTML={{
54+
__html: title!.replace(
55+
new RegExp(`(${eventsSearchTerm})`, 'gi'),
56+
(match, group) =>
57+
`<span style="color: black; background-color: ${
58+
group.toLowerCase() === eventsSearchTerm.toLowerCase() ? 'yellow' : 'inherit'
59+
}">${match}</span>`,
60+
),
61+
}}
62+
/>
63+
</strong>
64+
</h2>
65+
<p className="text-Grey-G500 dark:text-dark-two text-sm flex items-center gap-0.5 mb-1 font-nunito">
66+
<Location size={16} />
67+
<span className="font-medium">{location!}</span>
68+
</p>
69+
<p className="text-Grey-G500 dark:text-dark-two flex items-center gap-0.5 mb-2 font-nunito">
70+
<Timer1 size={16} />
71+
<span className="font-medium">{time}</span>
72+
</p>
73+
<div className="flex items-center font-montserrat">
74+
{participants?.length !== 0 && (
75+
<div className="flex items-center">
76+
{participants?.map((item, index) => {
77+
if (index >= 3) return;
78+
return (
79+
<div key={index} className="h-8 w-8 first:ml-0 -ml-1.5 rounded-full overflow-hidden">
80+
<Image
81+
src={item?.profileImage ?? '/assets/avatar.png'}
82+
height={32}
83+
width={32}
84+
alt="Attendant"
85+
className="object-top object-cover"
86+
/>
87+
</div>
88+
);
89+
})}
90+
{participants && participants?.length > 3 && (
91+
<span className="pl-3 text-sm font-medium font-nunito">
92+
+{participants?.length - 3} People registered
93+
</span>
94+
)}
95+
</div>
96+
)}
97+
</div>
98+
</div>
99+
</Link>
100+
</>
101+
);
102+
};
103+
104+
export default ExploreCard;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React, { useState, useEffect } from 'react';
2+
import Image from 'next/image';
3+
import { NotificationsProps, Notification } from '@/types';
4+
import { Activity } from 'iconsax-react';
5+
import { useStateCtx } from '@/context/StateCtx';
6+
7+
const NotificationDropDown = () => {
8+
const { OpenNotification, setOpenNotification } = useStateCtx();
9+
return <div>Notification</div>;
10+
};
11+
12+
export default NotificationDropDown;

v2/src/components/DropDowns/ProfileDropDown.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const ProfileDropDown = () => {
5757
</div>
5858
</Link>
5959
</div>
60-
<div className="flex items-center gap-2 cursor-pointer text-Grey-G500 dark:text-dark-two rounded-lg px-2">
60+
<div className="flex items-center gap-2 h-9 cursor-pointer text-Grey-G500 dark:text-dark-two rounded-lg px-2">
6161
<Link href="/" className="flex items-center gap-2">
6262
{/* <Button onClick={handleLogout} isLoading={isloading} className="px-2 h-9"> */}
6363
<LogoutCurve size={18} />

v2/src/components/Header/NavBarAuthenticated.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const NavBarAuthenticated = () => {
2020
<div className="flex items-center justify-between">
2121
<Link
2222
href="/"
23-
className="flex gap-14 text-primary-100 dark:text-dark-two text-[30px] font-medium font-chelsea"
23+
className="flex gap-14 text-primary-100 text-[30px] font-medium font-chelsea"
2424
>
2525
EVENTO
2626
</Link>
@@ -67,7 +67,7 @@ const NavBarAuthenticated = () => {
6767
</div>
6868
</div>
6969
</nav>
70-
<ProfileDropDown />
70+
{OpenProfile && <ProfileDropDown />}
7171
</header>
7272
);
7373
};

0 commit comments

Comments
 (0)