Skip to content

Commit

Permalink
presentations (#44)
Browse files Browse the repository at this point in the history
* presentations route, and presentation/:slug route as well

* presentation route, presentation/:slug as well

* changes based on figma design

* typo (xd)

* minor improvements

* fix presentaion page width

* presentation tile fix

* add slugify utility function

* implement build time slug and use static params

* use notFound instead of redirect('/error')

* add fallback

* presentation model extended & highlighted presentations

* fixes

* fixes

* added static data for featured presentation

* fix featured fix col-span

* works so far

* should be alright

* typo fix and removed testing code

* fix export

* Added buttons to frontpage tiles

* added mobile padding

* styling fixes and clsx

* merge conflict fix

* added seo for presentation pages

* presentation list responsiveness improvements

* improve yellow presenter label

* fix build

* fix it better

---------

Co-authored-by: Dkrisztan <[email protected]>
Co-authored-by: Miklos Daniel <[email protected]>
  • Loading branch information
3 people authored Feb 17, 2024
1 parent 778c91a commit d8d62ac
Show file tree
Hide file tree
Showing 15 changed files with 331 additions and 13 deletions.
Binary file removed public/img/nebula-thumbnail.png
Binary file not shown.
Binary file added public/img/nebula-thumbnail.webp
Binary file not shown.
5 changes: 4 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ const raleway = Raleway({ subsets: ['latin'], variable: '--font-raleway' });
const recharge = localFont({ src: '../../public/recharge.otf', variable: '--font-recharge' });

export const metadata: Metadata = {
title: 'Simonyi Konferencia - 2024. 03. 19.',
title: {
default: 'Simonyi Konferencia - 2024. 03. 19.',
template: 'Simonyi Konferencia - %s',
},
description: 'Magyarország legnagyobb egyetemi hallgatók által szervezett éves technológiai konferenciája.',
keywords:
'Simonyi Konferencia 2024, technológiai konferencia, egyetemi rendezvény, hallgatók, hallgatók szervezése, Simonyi Károly Szakkollégium, BME-VIK, innováció, digitalizáció, műszaki fejlesztések, tudományos esemény, inspiráló előadások, szakmai workshopok, Magyarország eseményei, fiatal tehetségek, digitális megoldások, jövő technológiái, iparági trendek, tudásátadás, innovatív gondolkodás, egyetemi közösség, kreatív technológia, networking lehetőségek, szakmai előadók, technológiai innovációk, informatikai fejlődés, egyetemi tapasztalatok, mérnöki világ, vezető szakemberek, digitális társadalom, tudományos találkozó',
Expand Down
18 changes: 17 additions & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import { redirect } from 'next/navigation';

import { metadata } from '@/app/layout';
import { ImageCarouselSection } from '@/components/image-carousel/image-carousel-section';
import Presentation from '@/components/presentation/Presentation';
import { SponsorSection } from '@/components/sponsors/sponsor-section';
import CountdownTile from '@/components/tiles/countdown-tile/countdown-tile';
import { GiveawayTile } from '@/components/tiles/giveaway-tile';
import { NewsletterTile } from '@/components/tiles/newsletter-tile';
import { PromoVideoTile } from '@/components/tiles/promo-video-tile';
import { RegisterTile } from '@/components/tiles/register-tile';
import { StatTile } from '@/components/tiles/stat-tile';
import { Tile } from '@/components/tiles/tile';
import { getIndexData } from '@/models/get-index-data';
import { kotlinPresentation, tresoritPresentation } from '@/models/staticPresentationData';

import konfLogo from '../../public/img/konf.svg';
import redPlanet from '../../public/img/red-planet.png';
Expand All @@ -25,7 +28,7 @@ export default async function Landing() {
<>
<div className='p-10 relative'>
<div className='max-w-md md:max-w-xl relative shadow-gloria rounded-full overflow-hidden mx-auto'>
<video className='h-full w-full' autoPlay playsInline loop muted poster='/img/nebula-thumbnail.png'>
<video className='h-full w-full' autoPlay playsInline loop muted poster='/img/nebula-thumbnail.webp'>
<source src='/video/nebula.mp4' type='video/mp4' />
</video>
</div>
Expand All @@ -44,7 +47,20 @@ export default async function Landing() {
<StatTile desc='percnyi előadás egy nap alatt' number='700+' />
<StatTile desc='előadó' number='14' />

<Tile className='sm:col-span-6'>
<Tile.Body className='md:px-10 px-5'>
<Presentation presentation={kotlinPresentation} isFrontPage />
</Tile.Body>
</Tile>

{data.promoVideo.youtubeUrl && <PromoVideoTile data={data.promoVideo} />}

<Tile className='sm:col-span-6'>
<Tile.Body className='md:px-10 px-5'>
<Presentation presentation={tresoritPresentation} isFrontPage />
</Tile.Body>
</Tile>

{data.giveaway.pictureUrl && <GiveawayTile data={data.giveaway} showLink={false} />}

<CountdownTile />
Expand Down
47 changes: 47 additions & 0 deletions src/app/presentations/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Metadata, ResolvingMetadata } from 'next';
import { notFound } from 'next/navigation';

import Presentation from '@/components/presentation/Presentation';
import { getIndexData } from '@/models/get-index-data';
import slugify from '@/utils/slugify';

export async function generateStaticParams() {
const data = await getIndexData();

return (
data?.presentations?.map((p) => ({
slug: slugify(p.title),
})) ?? []
);
}

type Props = {
params: { slug: string };
};

export async function generateMetadata({ params: { slug } }: Props, parent: ResolvingMetadata): Promise<Metadata> {
const data = await getIndexData();
const presentation = data?.presentations.find((p) => slugify(p.title) === slug);

return {
title: presentation?.title,
description: `${presentation?.presenter.name} "${presentation?.title}" című előadása a XXI. Simonyi Konferencián`,
keywords: `${(await parent).keywords}, ${presentation?.presenter.name}${presentation?.title
.split(' ')
.reduce((prev, curr) => `${prev}, ${curr}`, '')}`,
};
}

const getPresentationBySlug = async (slug: string) => {
const data = await getIndexData();
return data?.presentations.find((p) => slugify(p.title) === slug);
};

export default async function PresentationBySlug({ params }: { params: { slug: string } }) {
const presentation = await getPresentationBySlug(params.slug);
if (!presentation) {
notFound();
}

return <Presentation presentation={presentation} />;
}
63 changes: 63 additions & 0 deletions src/app/presentations/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import clsx from 'clsx';
import { Metadata } from 'next';
import Link from 'next/link';
import { notFound } from 'next/navigation';

import { Tile } from '@/components/tiles/tile';
import { getIndexData } from '@/models/get-index-data';
import slugify from '@/utils/slugify';

export const metadata: Metadata = {
title: 'Előadások',
description:
'Az előadások listája a XXI. Simonyi Konferencián, Magyarország legnagyobb egyetemi hallgatók által szervezett éves technológiai konferenciáján.',
};

export default async function Presentations() {
const data = await getIndexData();
if (!data || !data.presentations) {
notFound();
}
const presentations = data.presentations.sort((p1, p2) => p1.presenter.name.localeCompare(p2.presenter.name));

return (
<div className='flex flex-col max-w-6xl w-full px-6 xl:px-0'>
<h1 className='mb-16 mt-8'>Előadások</h1>

<div className='grid grid-cols-1 xs:grid-cols-2 lg:grid-cols-3 gap-8'>
{presentations.map((presentation) => (
<Tile key={presentation.title} clickable>
<Tile.Body lessPadding='[1px]'>
<div className='flex flex-col h-full'>
<Link className='h-full flex flex-col' href={`/presentations/${slugify(presentation.title)}`}>
<div>
<img
src={presentation.presenter.pictureUrl}
className='w-full aspect-square object-cover object-center rounded-[30px]'
alt='Presentation Image'
/>
<div className='z-20 px-5 py-2 absolute text-center left-1/2 -translate-x-[50%] -translate-y-[50%] shadow-md rounded-xl overflow-hidden bg-[#FFE500]'>
{presentation.presenter.name.split(',').map((pName) => (
<p className='whitespace-nowrap min-w-[200px] sm:min-w-[240px] text-2xl xs:text-xl sm:text-2xl text-black font-bold'>
{pName}
</p>
))}
</div>
</div>
<div
className={clsx(
'p-6 h-full flex items-center justify-center',
presentation.presenter.name.split(',').length > 1 && 'mt-6'
)}
>
<h2 className='text-center text-[24px] font-bold text-white pb-4'>{presentation.title}</h2>
</div>
</Link>
</div>
</Tile.Body>
</Tile>
))}
</div>
</div>
);
}
6 changes: 3 additions & 3 deletions src/components/footer/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { SocialButtons } from './social-buttons';

export function Footer() {
return (
<footer className='max-w-6xl mx-auto mt-24 w-full flex flex-col gap-10 mb-10 px-8 md:px-0'>
<footer className='max-w-6xl mx-auto mt-24 w-full flex flex-col gap-10 mb-10 px-8 xl:px-0'>
<div className='flex flex-col md:flex-row gap-6 justify-between'>
<div className='flex flex-col gap-4 w-full md:w-1/2 '>
<Image src={konfLogo} width={560} height={135} alt='Simonyi Konferencia' />
Expand All @@ -17,9 +17,9 @@ export function Footer() {
</div>

<div className='flex flex-col gap-4 text-center md:text-right text-xl font-medium'>
{/* <Link href='/presentations' className='brand-link'>
<Link href='/presentations' className='brand-link'>
Előadások
</Link> */}
</Link>
<Link href='/contact' className='brand-link'>
Kapcsolat
</Link>
Expand Down
8 changes: 4 additions & 4 deletions src/components/navbar/navbar-items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ const links = [
href: '/',
label: 'főoldal',
},
// {
// href: '/presentations',
// label: 'előadások',
// },
{
href: '/presentations',
label: 'előadások',
},
{
href: '/contact',
label: 'kapcsolat',
Expand Down
125 changes: 125 additions & 0 deletions src/components/presentation/Presentation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import clsx from 'clsx';
import Link from 'next/link';
import { FaArrowLeft } from 'react-icons/fa';

import { Presentation } from '@/models/models';
import slugify from '@/utils/slugify';

type PresentationProps = {
presentation: Presentation;
isFrontPage?: boolean | undefined;
};
export default async function Presentation({ presentation, isFrontPage }: PresentationProps) {
const { title, description, presenter, imageUrls } = presentation;

return (
<>
<div className={clsx('max-w-6xl w-full', isFrontPage ? '' : 'px-6 xl:px-0')}>
{!isFrontPage && (
<h3 className='mb-5 w-fit hover:text-brand'>
<Link href={`/presentations`}>
<div className='flex items-center'>
<FaArrowLeft />
<p className='ml-1'>Vissza az előadásokhoz </p>
</div>
</Link>
</h3>
)}
{!isFrontPage && <h1 className='mb-16'>{title}</h1>}
<div className='flex flex-col md:flex-row gap-8'>
{!isFrontPage && <p className='text-stone-200 text-[20px] whitespace-pre-line'>{description}</p>}
{isFrontPage && (
<div>
<p className='mb-12 text-3xl sm:text-[40px] font-bold leading-10'>{title}</p>
<p className='text-stone-200 text-[20px] whitespace-pre-line'>{description}</p>
<div className='flex flex-col sm:flex-row'>
{imageUrls?.map((image) => {
return (
<img
src={image}
alt='presentation images'
className='p-2 max-w-full max-h-[75px] object-contain mt-5'
/>
);
})}
</div>
</div>
)}
<div
className={clsx(
'flex flex-col items-center flex-shrink-0 text-center',
isFrontPage ? 'order-none' : 'order-first',
'md:order-last'
)}
>
<img
src={presenter.pictureUrl}
className={clsx(
'object-cover rounded-3xl',
isFrontPage ? 'w-72 h-72 sm:w-96 sm:h-96' : 'w-[250px] h-[250px] sm:w-[308px] sm:h-[308px]'
)}
alt='Presentation Image'
/>
<p className='block mt-4 text-[32px] leading-tight font-bold text-white-900'>{presenter.name}</p>
<p className='block mt-0.5 text-[20px] text-[#FFE500]'>{presenter.rank}</p>
{presenter.company && (
<div className='mt-1.5 bg-white rounded-xl max-w-[308px] max-h-[75px]'>
<img
src={presenter.company.logoUrl}
alt='Company logo'
className='p-2 max-w-full max-h-[75px] object-fit m-auto'
/>
</div>
)}
</div>
</div>
</div>
{isFrontPage && (
<div className='flex flex-col md:flex-row gap-6 md:gap-16 items-center pt-6 justify-center'>
<Link
href={`/presentations/${slugify(presentation.title)}`}
className='inline-flex items-center font-semibold text-xl text-white brand-link'
>
Részletek
<svg
className=' w-2.5 h-2.5 ms-2 rtl:rotate-180'
aria-hidden='true'
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 6 10'
>
<path
stroke='currentColor'
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
d='m1 9 4-4-4-4'
/>
</svg>
</Link>
<Link
href={'/presentations'}
className='inline-flex items-center font-semibold text-xl text-white brand-link'
>
Összes előadás
<svg
className=' w-2.5 h-2.5 ms-2 rtl:rotate-180'
aria-hidden='true'
xmlns='http://www.w3.org/2000/svg'
fill='none'
viewBox='0 0 6 10'
>
<path
stroke='currentColor'
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
d='m1 9 4-4-4-4'
/>
</svg>
</Link>
</div>
)}
</>
);
}
2 changes: 1 addition & 1 deletion src/components/tiles/organizer-tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ type Props = Organiser;
export function OrganiserTile({ name, emailAddress, pictureUrl, rank }: Props) {
return (
<Tile>
<Tile.Body hidePadding>
<Tile.Body lessPadding='2'>
<div className='flex flex-col h-full'>
<img src={pictureUrl} className='w-full aspect-square object-cover object-center' />
<div className='rounded-b-[30px] pt-4 px-3 pb-9 flex flex-col h-full gap-2 bg-[#101010]'>
Expand Down
13 changes: 10 additions & 3 deletions src/components/tiles/tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,19 @@ function TileBase({ children, className, clickable }: Props) {
type TileBodyProps = {
children: React.ReactNode;
className?: string;
hidePadding?: boolean;
lessPadding?: string;
};

function TileBody({ children, className, hidePadding = false }: TileBodyProps) {
function TileBody({ children, className, lessPadding }: TileBodyProps) {
return (
<div className={clsx(styles['card-body'], hidePadding ? 'p-2' : 'p-6 sm:p-10', 'w-full h-full', className)}>
<div
className={clsx(
styles['card-body'],
lessPadding ? `p-${lessPadding}` : 'p-6 sm:p-10',
'w-full h-full',
className
)}
>
{children}
</div>
);
Expand Down
1 change: 1 addition & 0 deletions src/models/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export interface Presentation {
endTime: string;
description: string;
questionsUrl: string; // még kérdéses, hogy így lesz-e
imageUrls?: string[];
}

export interface RegistraionData {
Expand Down
Loading

0 comments on commit d8d62ac

Please sign in to comment.