Skip to content

Commit

Permalink
feat: events section on homepage (#221)
Browse files Browse the repository at this point in the history
Co-authored-by: GetPsyched <[email protected]>
  • Loading branch information
geekysilento and GetPsyched authored Sep 27, 2024
1 parent ecfee26 commit 650dd8c
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 2 deletions.
180 changes: 180 additions & 0 deletions app/[locale]/events.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import { desc, eq } from 'drizzle-orm';
import Image from 'next/image';
import Link from 'next/link';

import { BouncyArrowButton, Button } from '~/components/buttons';
import Heading from '~/components/heading';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '~/components/inputs';
import { Card, CardContent, CardDescription, CardTitle } from '~/components/ui';
import { getTranslations } from '~/i18n/translations';
import { cn, getKeys } from '~/lib/utils';
import { db, type events as eventsSchema } from '~/server/db';
import { getS3Url } from '~/server/s3';

export default async function Events({
category: currentCategory,
locale,
}: {
category:
| (typeof eventsSchema.category.enumValues)[number]
| 'recents'
| 'featured';
locale: string;
}) {
const text = (await getTranslations(locale)).Events;

const events = await db.query.events.findMany({
where: (event) => {
if (currentCategory === 'recents') return undefined;
else if (currentCategory === 'featured')
return eq(event.isFeatured, true);
return eq(event.category, currentCategory);
},
orderBy: (event) => [desc(event.startDate)],
limit: 6,
});

return (
<article
className="relative bg-cover bg-no-repeat pb-32 pt-[72px] md:pb-40"
id="events"
style={{
backgroundImage: `url('${getS3Url()}/assets/dottedarrows-1.png')`,
}}
>
<Heading
className="container"
glyphDirection="ltr"
heading="h2"
href="#events"
text={text.title}
/>

<article className="container relative lg:flex lg:gap-16">
<ol
className={cn(
'hidden lg:block',
'sticky top-[88px]',
'h-fit min-w-72 space-y-4'
)}
>
{getKeys(text.categories).map((category, index) => (
<li key={index}>
<Link
href={{ query: { eventsCategory: category } }}
scroll={false}
>
<Button
className={cn(
'w-full flex-auto rounded-xl text-center font-serif text-shade-light',
'border border-primary-700 p-6 text-2xl drop-shadow-2xl',
'bg-neutral-50 text-primary-700',
'hover:bg-primary-700 hover:text-shade-light',
category === currentCategory
? 'bg-primary-700 text-shade-light'
: 'bg-opacity-60'
)}
>
{text.categories[category]}
</Button>
</Link>
</li>
))}
</ol>
<section className="my-4 flex justify-between drop-shadow-2xl lg:hidden">
<Select defaultValue={text.categories.featured}>
<SelectTrigger className="w-[70%] px-4 py-5 text-shade-light">
<SelectValue />
</SelectTrigger>
<SelectContent>
{getKeys(text.categories).map((category, index) => (
<SelectItem key={index} value={text.categories[category]}>
{text.categories[category]}
</SelectItem>
))}
</SelectContent>
</Select>

<BouncyArrowButton
buttonProps={{
className: 'text-base md:text-lg mx-auto',
variant: 'link',
}}
linkProps={{ href: `/${locale}/events` }}
text={text.viewAll}
/>
</section>

<section className="flex flex-col gap-4">
<BouncyArrowButton
buttonProps={{
className:
'ml-auto text-lg lg:inline-flex items-center gap-1 hidden',
variant: 'link',
}}
linkProps={{ href: `/${locale}/events` }}
text={text.viewAll}
/>
<ol className="grid grid-cols-1 grid-rows-6 gap-6 lg:grid-cols-5 lg:grid-rows-3">
{events.map(({ title, content, startDate }, index) => (
<li
key={index}
className={cn(
index % 3 === 0 || index === 4
? 'lg:col-span-3'
: 'lg:col-span-2',
'h-[448px] list-none'
)}
>
<Card
className={cn('flex h-full flex-col border-0 bg-shade-light')}
>
<Image
alt={title}
className="h-64 w-full rounded-t-md object-cover"
height={0}
src={`${getS3Url()}/events/${startDate.slice(0, 4)}/${startDate.slice(5, 7)}/${title}/image01.jpg`}
width={0}
/>
<CardContent className="relative pt-3">
<time className="absolute -top-10 right-8 flex h-20 w-16 flex-col items-center justify-center bg-primary-500 bg-opacity-90 text-shade-light">
<span className="font-serif text-2xl">
{new Intl.DateTimeFormat('en-GB', {
day: '2-digit',
}).format(new Date(startDate))}
</span>
<span className="font-serif text-xl">
{new Intl.DateTimeFormat('en-GB', { month: 'short' })
.format(new Date(startDate))
.substring(0, 3)
.toUpperCase()}
</span>
</time>
<CardTitle className="mr-20 lg:text-2xl">{title}</CardTitle>
<CardDescription className="line-clamp-3">
{content}
</CardDescription>
</CardContent>
</Card>
</li>
))}
</ol>
</section>
</article>
{/* fixme: button overlap issue */}
{/* <Image
alt="arjuna"
src="assets/arjuna-1.png"
width={0}
height={0}
className="absolute bottom-0 left-0 lg:size-[28rem]"
/> */}
</article>
);
}
9 changes: 9 additions & 0 deletions app/[locale]/events/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { WorkInProgressStatus } from '~/components/status';

export default function Events({
params: { locale },
}: {
params: { locale: string };
}) {
return <WorkInProgressStatus locale={locale} />;
}
14 changes: 12 additions & 2 deletions app/[locale]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,24 @@ import {
import Heading from '~/components/heading';
import MessageCard from '~/components/message-card';
import { getTranslations } from '~/i18n/translations';
import { type notifications } from '~/server/db';
import { type events, type notifications } from '~/server/db';

import Events from './events';

export default async function Home({
params: { locale },
searchParams: { notificationCategory = 'academic' },
searchParams: {
notificationCategory = 'academic',
eventsCategory = 'featured',
},
}: {
params: { locale: string };
searchParams: {
notificationCategory?: (typeof notifications.category.enumValues)[number];
eventsCategory?:
| (typeof events.category.enumValues)[number]
| 'recents'
| 'featured';
};
}) {
const text = (await getTranslations(locale)).Main;
Expand Down Expand Up @@ -125,6 +134,7 @@ export default async function Home({
</AutoplayCarousel>

<Notifications category={notificationCategory} locale={locale} />
<Events category={eventsCategory} locale={locale} />

<section className="container mb-32 mt-10" id="directors-corner">
<Heading
Expand Down
10 changes: 10 additions & 0 deletions i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ const text: Translations = {
},
viewAll: 'View All',
},
Events: {
title: 'EVENTS & NEWS',
categories: {
featured: 'Featured',
recents: 'Recents',
student: 'Student',
faculty: 'Faculty',
},
viewAll: 'View All',
},
NotFound: {
title: 'Not Found',
description: 'Could not find requested resource',
Expand Down
11 changes: 11 additions & 0 deletions i18n/hi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ const text: Translations = {
laboratories: 'प्रयोगशालाएँ',
achievements: 'छात्र उपलब्धियाँ',
},
Events: {
title: 'कार्यक्रम और समाचार',
categories: {
featured: 'विशेष',
recents: 'हाल ही में',
student: 'छात्र',
faculty: 'शिक्षक',
},
viewAll: 'सभी देखें',
},

FacultyAndStaff: {
placeholder: 'नाम या ईमेल से खोजें',
departmentHead: 'विभागाध्यक्ष',
Expand Down
10 changes: 10 additions & 0 deletions i18n/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ export interface Translations {
};
viewAll: string;
};
Events: {
title: string;
categories: {
featured: string;
recents: string;
student: string;
faculty: string;
};
viewAll: string;
};
NotFound: { title: string; description: string; backHome: string };
Profile: {
logout: string;
Expand Down
34 changes: 34 additions & 0 deletions server/db/schema/events.schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
boolean,
date,
pgTable,
serial,
text,
timestamp,
uniqueIndex,
varchar,
} from 'drizzle-orm/pg-core';

export const events = pgTable(
'events',
{
id: serial('id').primaryKey(),
title: varchar('title', { length: 256 }).unique().notNull(),
content: text('content'),
category: varchar('category', {
enum: ['student', 'faculty'],
}).notNull(),
isFeatured: boolean('is_featured').default(false).notNull(),
startDate: date('start_date').notNull(),
endDate: date('end_date').notNull(),
createdAt: timestamp('created_at').defaultNow().notNull(),
updatedAt: timestamp('updated_at')
.$onUpdate(() => new Date())
.notNull(),
},
(events) => {
return {
eventsTitleIndex: uniqueIndex('events_title_idx').on(events.title),
};
}
);
1 change: 1 addition & 0 deletions server/db/schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export * from './deans.schema';
export * from './department-heads.schema';
export * from './departments.schema';
export * from './doctorates.schema';
export * from './events.schema';
export * from './faculty.schema';
export * from './faq.schema';
export * from './hostels.schema';
Expand Down

0 comments on commit 650dd8c

Please sign in to comment.