Add new home page
This commit is contained in:
parent
9b090d212a
commit
d668093240
|
@ -7,7 +7,7 @@
|
|||
"contact": "Контакти"
|
||||
},
|
||||
"main": {
|
||||
"date": "2-ри – 3-ти",
|
||||
"date": "2 – 3",
|
||||
"monthYear": "Ноември 2024",
|
||||
"titleLocation": "Иновативен форум \"Джон Атанасов\" – София Тех Парк",
|
||||
"countdownTimer": {
|
||||
|
@ -26,6 +26,11 @@
|
|||
"volunteers": "Присъединете се като доброволец",
|
||||
"partners": "Подкрепете събитието като партньор"
|
||||
},
|
||||
"news": {
|
||||
"title": "Новини",
|
||||
"cardButton": "Прочети",
|
||||
"button": "Виж всички"
|
||||
},
|
||||
"partners": {
|
||||
"sponsors": "Sponsors",
|
||||
"media": "Media partners"
|
||||
|
|
|
@ -8,24 +8,29 @@
|
|||
},
|
||||
"main": {
|
||||
"date": "2 - 3",
|
||||
"monthYear": "November 2024",
|
||||
"monthYear": "November, 2024",
|
||||
"titleLocation": "Innovation forum \"John Atanasoff\" – Sofia Tech Park",
|
||||
"countdownTimer": {
|
||||
"title": "Until OpenFest remain:",
|
||||
"title": "OpenFest starts in:",
|
||||
"days": "Days",
|
||||
"hours": "Hours",
|
||||
"minutes": "Minutes"
|
||||
},
|
||||
"description": {
|
||||
"title": "What is OpenFest?",
|
||||
"title": "What is OpenFest...",
|
||||
"text": "OpenFest is the biggest Bulgarian conference dedicated to the free culture, free knowledge sharing, free and open-source software. The event is organized by volunteers and is free to attend. OpenFest is held annually in Sofia, Bulgaria."
|
||||
},
|
||||
"cfp": {
|
||||
"title": "How to participate in OpenFest 2024",
|
||||
"title": "How to participate in OpenFest 2024?",
|
||||
"lecture": "Take part with a lecture, a workshop or a booth",
|
||||
"volunteers": "Join us as a volunteer",
|
||||
"partners": "Support the event as a partner"
|
||||
},
|
||||
"news": {
|
||||
"title": "News",
|
||||
"cardButton": "Read",
|
||||
"button": "See all"
|
||||
},
|
||||
"partners": {
|
||||
"sponsors": "Sponsors",
|
||||
"media": "Media partners"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -30,7 +30,7 @@
|
|||
"@types/react": "^18.3.5",
|
||||
"@types/react-dom": "^18",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^9.10.0",
|
||||
"eslint-config-next": "^14.2.8",
|
||||
"install": "^0.13.0",
|
||||
"npm": "^10.8.3",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
|
@ -1,7 +1,6 @@
|
|||
import { Inter } from 'next/font/google';
|
||||
import { i18n } from '../../../i18n-config';
|
||||
|
||||
import NavBar from '@/components/NavBar';
|
||||
import NavBar from '../../components/NavBar';
|
||||
import Footer from '@/components/Footer';
|
||||
|
||||
import '@/styles/globals.css';
|
||||
|
@ -10,8 +9,6 @@ export async function generateStaticParams() {
|
|||
return i18n.locales.map((locale) => ({ lang: locale }));
|
||||
}
|
||||
|
||||
const inter = Inter({ subsets: ['latin'] });
|
||||
|
||||
export const metadata = {
|
||||
title: 'OpenFest 2024',
|
||||
description: 'Да се видим на OpenFest 2024!',
|
||||
|
@ -21,12 +18,12 @@ export default function RootLayout({ children, params }) {
|
|||
return (
|
||||
<html lang={params.lang}>
|
||||
<body
|
||||
className={`${inter.className} flex min-h-screen flex-col text-white md:text-lg lg:text-xl`}
|
||||
className={`flex min-h-screen flex-col font-openSans text-white md:text-lg lg:text-xl`}
|
||||
>
|
||||
<header>
|
||||
<NavBar lang={params.lang} />
|
||||
</header>
|
||||
{children}
|
||||
<main>{children}</main>
|
||||
<Footer lang={params.lang} />
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,104 +1,88 @@
|
|||
import CountDownTimer from '@/components/CountDownTimer';
|
||||
import NewsFeed from '@/components/NewsFeed';
|
||||
import Partners from '@/components/Partners';
|
||||
// import { getSortedPostsData } from '../../lib/posts';
|
||||
import Image from 'next/image';
|
||||
import { getDictionary } from '@/dictionaries';
|
||||
|
||||
export default async function Home({ params }) {
|
||||
const { lang } = params;
|
||||
const dictionary = await getDictionary(lang);
|
||||
// const { posts } = await getSortedPostsData(lang);
|
||||
|
||||
return (
|
||||
<>
|
||||
<section>
|
||||
<div className='bg-gradient-to-r from-sky-500 to-indigo-500'>
|
||||
<div className='mx-auto max-w-2xl py-32 sm:py-48 lg:py-56'>
|
||||
<section className='h-[65vh] bg-home-bg bg-cover sm:h-[75vh]'>
|
||||
<div className='container flex h-full flex-col justify-center gap-10 text-black sm:gap-16'>
|
||||
<div className='text-center'>
|
||||
<h1 className='text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl'>
|
||||
<p className='text-xl sm:text-3xl'>{dictionary.main.monthYear}</p>
|
||||
<h1 className='text-8xl font-semibold leading-none sm:text-[9rem]'>
|
||||
{dictionary.main.date}
|
||||
</h1>
|
||||
<h2 className='text-gray-900'>{dictionary.main.monthYear}</h2>
|
||||
<p className='mt-6 text-lg leading-8 text-gray-600'>
|
||||
</div>
|
||||
<div className='text-center'>
|
||||
<p className='pb-2 text-2xl font-semibold sm:pb-4 sm:text-5xl'>
|
||||
“Let’s share the freedom!”
|
||||
</p>
|
||||
<p className='text-xl sm:text-3xl'>
|
||||
{dictionary.main.titleLocation}
|
||||
</p>
|
||||
{/* <div className='mt-10 flex items-center justify-center gap-x-6'>
|
||||
<a
|
||||
href='#'
|
||||
className='rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600'
|
||||
>
|
||||
Get started
|
||||
</a>
|
||||
<a
|
||||
href='#'
|
||||
className='text-sm font-semibold leading-6 text-gray-900'
|
||||
>
|
||||
Learn more <span aria-hidden='true'>→</span>
|
||||
</a>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<CountDownTimer props={dictionary.main.countdownTimer} />
|
||||
|
||||
<section className='bg-[#E2EFFE] px-24 py-12'>
|
||||
<h2 className='pb-16 text-center text-[2.2rem] text-[#004394]'>
|
||||
<section className='bg-blue-8'>
|
||||
<div className='container flex flex-col gap-4 sm:gap-8'>
|
||||
<h2 className='text-center text-2xl text-blue-2 sm:text-4xl'>
|
||||
{dictionary.main.description.title}
|
||||
</h2>
|
||||
<div className='flex-col md:flex md:flex-row'>
|
||||
<div className='mx-2 text-center text-[#004394]'>
|
||||
{dictionary.main.description.text}
|
||||
<div className='flex flex-col gap-6 sm:flex-row'>
|
||||
<div className='flex-1'>
|
||||
<p> {dictionary.main.description.text}</p>
|
||||
</div>
|
||||
<div className='flex-1'>
|
||||
<Image
|
||||
src='/images/openfest-2.webp'
|
||||
width='620'
|
||||
height='380'
|
||||
></Image>
|
||||
</div>
|
||||
<div className='mx-2 text-center text-[#004394]'>
|
||||
{dictionary.main.description.text}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className='pb-16 text-center text-[2.2rem] text-[#004394]'>
|
||||
<div className='container'>
|
||||
<h2 className='pb-4 text-center text-2xl text-blue-2 sm:pb-8 sm:text-4xl'>
|
||||
{dictionary.main.cfp.title}
|
||||
</h2>
|
||||
{/* <dl className='mt-5 grid grid-cols-1 gap-5 sm:grid-cols-3'> */}
|
||||
<dl className='mt-5 grid grid-cols-1 place-items-center gap-1 sm:grid-cols-3'>
|
||||
<div className='max-w-[350px] overflow-hidden rounded-lg bg-[#004394] px-4 py-5 text-center shadow sm:p-6'>
|
||||
<dt className='truncate text-sm font-medium text-[#004394]'>
|
||||
<div className='m-auto mb-2 flex h-20 w-20 items-center justify-center rounded-full bg-[#C8E0FC] text-[2.3rem]'>
|
||||
<div className='flex flex-col gap-4 sm:flex-row sm:gap-8'>
|
||||
<div className='flex basis-1/3 flex-col items-center justify-center gap-3 rounded-xl bg-blue-2 p-6 sm:gap-6'>
|
||||
<div className='flex h-20 w-20 items-center justify-center rounded-full bg-blue-8 text-4xl text-blue-2 sm:h-24 sm:w-24 sm:text-5xl'>
|
||||
<i className='fa-solid fa-lightbulb'></i>
|
||||
</div>
|
||||
</dt>
|
||||
<dd className='mt-1 text-[22px] font-semibold text-[#F2F5F9]'>
|
||||
<p className='text-center text-white'>
|
||||
{dictionary.main.cfp.lecture}
|
||||
</dd>
|
||||
</p>
|
||||
</div>
|
||||
<div className='max-w-[350px] overflow-hidden rounded-lg bg-[#004394] px-4 py-5 text-center shadow sm:p-6'>
|
||||
<dt className='truncate text-sm font-medium text-[#004394]'>
|
||||
<div className='m-auto mb-2 flex h-20 w-20 items-center justify-center rounded-full bg-[#C8E0FC] text-[2.3rem]'>
|
||||
<div className='flex basis-1/3 flex-col items-center justify-center gap-3 rounded-xl bg-blue-2 p-6 sm:gap-6'>
|
||||
<div className='flex h-20 w-20 items-center justify-center rounded-full bg-blue-8 text-4xl text-blue-2 sm:h-24 sm:w-24 sm:text-5xl'>
|
||||
<i className='fa-solid fa-helmet-safety'></i>
|
||||
</div>
|
||||
</dt>
|
||||
<dd className='mt-1 text-[22px] font-semibold text-[#F2F5F9]'>
|
||||
<p className='text-center text-white'>
|
||||
{dictionary.main.cfp.volunteers}
|
||||
</dd>
|
||||
</p>
|
||||
</div>
|
||||
<div className='max-w-[350px] overflow-hidden rounded-lg bg-[#004394] px-4 py-6 text-center shadow sm:p-6'>
|
||||
<dt className='truncate text-sm font-medium text-[#004394]'>
|
||||
<div className='m-auto mb-2 flex h-20 w-20 items-center justify-center rounded-full bg-[#C8E0FC] text-[2.3rem]'>
|
||||
<div className='flex basis-1/3 flex-col items-center justify-center gap-3 rounded-xl bg-blue-2 p-6 sm:gap-6'>
|
||||
<div className='flex h-20 w-20 items-center justify-center rounded-full bg-blue-8 text-4xl text-blue-2 sm:h-24 sm:w-24 sm:text-5xl'>
|
||||
<i className='fa-solid fa-handshake-angle'></i>
|
||||
</div>
|
||||
</dt>
|
||||
<dd className='mt-1 text-[22px] font-semibold text-[#F2F5F9]'>
|
||||
<p className='text-center text-white'>
|
||||
{dictionary.main.cfp.partners}
|
||||
</dd>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dl>
|
||||
</section>
|
||||
<main>
|
||||
<NewsFeed />
|
||||
<Partners props={lang} />
|
||||
</main>
|
||||
<NewsFeed lang={lang} />
|
||||
<Partners lang={lang} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,8 +8,9 @@ const CountDownTimer = ({ props }) => {
|
|||
|
||||
useEffect(() => {
|
||||
const targetDate = new Date('2024-11-02T09:30:00+03:00');
|
||||
const countDownIntervalTime = 1000;
|
||||
|
||||
const interval = setInterval(() => {
|
||||
const updateCountDown = () => {
|
||||
const now = new Date();
|
||||
|
||||
const diff = targetDate.getTime() - now.getTime();
|
||||
|
@ -22,54 +23,69 @@ const CountDownTimer = ({ props }) => {
|
|||
|
||||
const m = Math.floor((diff / (1000 * 60)) % 60);
|
||||
setMinutes(m);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
// Set time
|
||||
updateCountDown();
|
||||
|
||||
// Set interval
|
||||
const interval = setInterval(updateCountDown, countDownIntervalTime);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section className='m-12 mb-20 pt-6'>
|
||||
{/* <span className='mb-12 mt-4 block text-3xl text-black'>
|
||||
<section>
|
||||
<div className='container flex flex-col gap-4 sm:gap-8'>
|
||||
<h2 className='text-center text-2xl text-blue-2 sm:text-start sm:text-4xl'>
|
||||
{props.title}
|
||||
</span> */}
|
||||
<div className='flex justify-evenly'>
|
||||
<div className='relative h-[256px] w-[256px]'>
|
||||
</h2>
|
||||
<div className='flex flex-col items-center justify-evenly gap-8 lg:flex-row'>
|
||||
<div className='relative h-40 w-40 lg:h-64 lg:w-64'>
|
||||
<div className='absolute inset-0 rotate-[-45deg] overflow-hidden rounded-full bg-[#A9CDF7]'>
|
||||
<div className='absolute left-0 top-0 h-full w-1/2'></div>
|
||||
<div className='absolute left-0 top-0 h-full w-1/2 bg-[#C8E0FC]'></div>
|
||||
</div>
|
||||
<div className='absolute inset-0 flex items-center justify-center'>
|
||||
<span className='text-center font-bold text-gray-800'>
|
||||
<p className='pb-[38px] pt-[14px] text-[85px]'>{days}</p>
|
||||
<p className='text-[36px] font-light'> {props.days}</p>
|
||||
<p className='pb-1 pt-2 text-5xl lg:pb-3 lg:pt-4 lg:text-8xl'>
|
||||
{days}
|
||||
</p>
|
||||
<p className='text-xl font-light lg:text-5xl'> {props.days}</p>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className='relative h-[256px] w-[256px]'>
|
||||
<div className='relative h-40 w-40 lg:h-64 lg:w-64'>
|
||||
<div className='absolute inset-0 rotate-[-45deg] overflow-hidden rounded-full bg-[#A9CDF7]'>
|
||||
<div className='absolute left-0 top-0 h-full w-1/2'></div>
|
||||
<div className='absolute left-0 top-0 h-full w-1/2 bg-[#C8E0FC]'></div>
|
||||
<div className='absolute left-0 top-0 h-full w-full'></div>
|
||||
</div>
|
||||
<div className='absolute inset-0 flex items-center justify-center'>
|
||||
<span className='text-center font-bold text-gray-800'>
|
||||
<p className='pb-[38px] pt-[14px] text-[85px]'>{hours}</p>
|
||||
<p className='text-[36px] font-light'> {props.hours}</p>
|
||||
<p className='pb-1 pt-2 text-5xl lg:pb-3 lg:pt-4 lg:text-8xl'>
|
||||
{hours}
|
||||
</p>
|
||||
<p className='text-xl font-light lg:text-5xl'> {props.hours}</p>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className='relative h-[256px] w-[256px]'>
|
||||
<div className='relative h-40 w-40 lg:h-64 lg:w-64'>
|
||||
<div className='absolute inset-0 rotate-[-45deg] overflow-hidden rounded-full bg-[#A9CDF7]'>
|
||||
<div className='absolute left-0 top-0 h-full w-1/2'></div>
|
||||
<div className='absolute left-0 top-0 h-full w-1/2 bg-[#C8E0FC]'></div>
|
||||
<div className='absolute right-0 top-0 h-full w-1/2 bg-[#C8E0FC]'></div>
|
||||
</div>
|
||||
<div className='absolute inset-0 flex items-center justify-center'>
|
||||
<span className='text-center font-bold text-gray-800'>
|
||||
<p className='pb-[38px] pt-[14px] text-[85px]'>{minutes}</p>
|
||||
<p className='text-[36px] font-light'> {props.minutes}</p>
|
||||
<p className='pb-1 pt-2 text-5xl lg:pb-3 lg:pt-4 lg:text-8xl'>
|
||||
{minutes}
|
||||
</p>
|
||||
<p className='text-xl font-light lg:text-5xl'>
|
||||
{props.minutes}
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -35,40 +35,14 @@ const Navbar = async ({ lang }) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<nav className='my-6 bg-white'>
|
||||
<div className='mx-auto flex max-w-screen-xl flex-wrap items-center justify-between p-4'>
|
||||
<a
|
||||
href='https://openfest.org/'
|
||||
className='flex items-center space-x-3 rtl:space-x-reverse'
|
||||
>
|
||||
<nav className='container flex flex-col items-center justify-between gap-4 bg-white text-black sm:flex-row'>
|
||||
<div>
|
||||
<a href='https://openfest.org/' className='flex items-center'>
|
||||
<Image src={OpenFestLogo} alt='OpenFest Logo' width={256} />
|
||||
</a>
|
||||
{/* <button
|
||||
data-collapse-toggle='navbar-default'
|
||||
type='button'
|
||||
class='inline-flex h-10 w-10 items-center justify-center rounded-lg p-2 text-sm text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 md:hidden dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600'
|
||||
aria-controls='navbar-default'
|
||||
aria-expanded='false'
|
||||
>
|
||||
<span class='sr-only'>Open main menu</span>
|
||||
<svg
|
||||
class='h-5 w-5'
|
||||
aria-hidden='true'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
fill='none'
|
||||
viewBox='0 0 17 14'
|
||||
>
|
||||
<path
|
||||
stroke='currentColor'
|
||||
stroke-linecap='round'
|
||||
stroke-linejoin='round'
|
||||
stroke-width='2'
|
||||
d='M1 1h15M1 7h15M1 13h15'
|
||||
/>
|
||||
</svg>
|
||||
</button> */}
|
||||
<div className='hidden w-full md:block md:w-auto' id='navbar-default'>
|
||||
<ul className='mt-4 flex flex-col font-medium text-[#0B1C30] md:mt-0 md:flex-row md:space-x-8 md:border-0 md:bg-white md:p-0 rtl:space-x-reverse'>
|
||||
</div>
|
||||
<div className='flex items-center justify-center'>
|
||||
<ul className='flex flex-wrap items-center justify-center gap-4 sm:gap-8'>
|
||||
<li>
|
||||
<a href='#' className='' aria-current='page'>
|
||||
{dictionary.nav.home}
|
||||
|
@ -99,7 +73,15 @@ const Navbar = async ({ lang }) => {
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
//<div className='mx-auto flex max-w-screen-xl flex-wrap items-center justify-between p-4'>
|
||||
// <div
|
||||
// className='hidden w-full md:block md:w-auto'
|
||||
// id='navbar-default'
|
||||
// >
|
||||
// // </div>
|
||||
//</div>
|
||||
}
|
||||
</nav>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -1,137 +1,50 @@
|
|||
import Image from 'next/image';
|
||||
import { getDictionary } from '@/dictionaries';
|
||||
import { getSortedPostsData } from '@/lib/posts';
|
||||
|
||||
const posts = [
|
||||
{
|
||||
title: 'Boost your conversion rate',
|
||||
href: '#',
|
||||
category: { name: 'Article', href: '#' },
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Architecto accusantium praesentium eius, ut atque fuga culpa, similique sequi cum eos quis dolorum.',
|
||||
date: 'Mar 16, 2020',
|
||||
datetime: '2020-03-16',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1496128858413-b36217c2ce36?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1679&q=80',
|
||||
readingTime: '6 min',
|
||||
author: {
|
||||
name: 'Roel Aufderehar',
|
||||
href: '#',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'How to use search engine optimization to drive sales',
|
||||
href: '#',
|
||||
category: { name: 'Video', href: '#' },
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit facilis asperiores porro quaerat doloribus, eveniet dolore. Adipisci tempora aut inventore optio animi., tempore temporibus quo laudantium.',
|
||||
date: 'Mar 10, 2020',
|
||||
datetime: '2020-03-10',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1547586696-ea22b4d4235d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1679&q=80',
|
||||
readingTime: '4 min',
|
||||
author: {
|
||||
name: 'Brenna Goyette',
|
||||
href: '#',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Improve your customer experience',
|
||||
href: '#',
|
||||
category: { name: 'Case Study', href: '#' },
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Sint harum rerum voluptatem quo recusandae magni placeat saepe molestiae, sed excepturi cumque corporis perferendis hic.',
|
||||
date: 'Feb 12, 2020',
|
||||
datetime: '2020-02-12',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1492724441997-5dc865305da7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1679&q=80',
|
||||
readingTime: '11 min',
|
||||
author: {
|
||||
name: 'Daniela Metz',
|
||||
href: '#',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1487412720507-e7ab37603c6f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
||||
},
|
||||
},
|
||||
];
|
||||
const NewsFeed = async ({ lang }) => {
|
||||
const dictionary = await getDictionary(lang);
|
||||
const posts = await getSortedPostsData(lang);
|
||||
|
||||
const NewsFeed = () => {
|
||||
return (
|
||||
<div className='relative bg-gray-50 px-4 pb-20 pt-16 sm:px-6 lg:px-8 lg:pb-28 lg:pt-24'>
|
||||
<div className='absolute inset-0'>
|
||||
<div className='h-1/3 bg-white sm:h-2/3' />
|
||||
</div>
|
||||
<div className='relative mx-auto max-w-7xl'>
|
||||
<div className='text-center'>
|
||||
<h2 className='text-3xl font-extrabold tracking-tight text-gray-900 sm:text-4xl'>
|
||||
From the blog
|
||||
<section className='bg-blue-8'>
|
||||
<div className='container flex flex-col gap-4 sm:gap-8'>
|
||||
<h2 className='text-center text-2xl text-blue-2 sm:text-start sm:text-4xl'>
|
||||
{dictionary.main.news.title}
|
||||
</h2>
|
||||
<p className='mx-auto mt-3 max-w-2xl text-xl text-gray-500 sm:mt-4'>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ipsa
|
||||
libero labore natus atque, ducimus sed.
|
||||
</p>
|
||||
</div>
|
||||
<div className='mx-auto mt-12 grid max-w-lg gap-5 lg:max-w-none lg:grid-cols-3'>
|
||||
{posts.map((post) => (
|
||||
<div className='flex flex-col gap-4 sm:flex-row sm:gap-8'>
|
||||
{posts.map((post) => {
|
||||
return (
|
||||
<div
|
||||
key={post.title}
|
||||
className='flex flex-col overflow-hidden rounded-lg shadow-lg'
|
||||
className='flex basis-1/3 flex-col overflow-hidden rounded-xl shadow-xl'
|
||||
>
|
||||
<div className='flex-shrink-0'>
|
||||
<Image
|
||||
className='h-48 w-full object-cover'
|
||||
src={post.imageUrl}
|
||||
alt=''
|
||||
/>
|
||||
<div>
|
||||
<Image src={post.imageUrl} width='400' height='190'></Image>
|
||||
</div>
|
||||
<div className='flex flex-1 flex-col justify-between bg-white p-6'>
|
||||
<div className='flex-1'>
|
||||
<p className='text-sm font-medium text-indigo-600'>
|
||||
<a href={post.category.href} className='hover:underline'>
|
||||
{post.category.name}
|
||||
</a>
|
||||
</p>
|
||||
<a href={post.href} className='mt-2 block'>
|
||||
<p className='text-xl font-semibold text-gray-900'>
|
||||
{post.title}
|
||||
</p>
|
||||
<p className='mt-3 text-base text-gray-500'>
|
||||
{post.description}
|
||||
</p>
|
||||
<div className='flex h-full flex-1 flex-col gap-2 bg-white p-6 text-center sm:gap-4'>
|
||||
<p className='text-blue-2'>{post.title}</p>
|
||||
<p className='text-sm opacity-50'>{post.date}</p>
|
||||
<a
|
||||
href='#'
|
||||
className='mx-auto mt-auto self-baseline rounded-3xl bg-blue-2 px-12 py-2'
|
||||
>
|
||||
{dictionary.main.news.cardButton}
|
||||
</a>
|
||||
</div>
|
||||
<div className='mt-6 flex items-center'>
|
||||
<div className='flex-shrink-0'>
|
||||
<a href={post.author.href}>
|
||||
<span className='sr-only'>{post.author.name}</span>
|
||||
<Image
|
||||
className='h-10 w-10 rounded-full'
|
||||
src={post.author.imageUrl}
|
||||
alt=''
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<a
|
||||
href='#'
|
||||
className='mt-4 flex items-center justify-center gap-4 self-center rounded-3xl bg-blue-2 px-12 py-2 sm:self-baseline'
|
||||
>
|
||||
{dictionary.main.news.button}
|
||||
<i className='fa-solid fa-arrow-right'></i>
|
||||
</a>
|
||||
</div>
|
||||
<div className='ml-3'>
|
||||
<p className='text-sm font-medium text-gray-900'>
|
||||
<a href={post.author.href} className='hover:underline'>
|
||||
{post.author.name}
|
||||
</a>
|
||||
</p>
|
||||
<div className='flex space-x-1 text-sm text-gray-500'>
|
||||
<time dateTime={post.datetime}>{post.date}</time>
|
||||
<span aria-hidden='true'>·</span>
|
||||
<span>{post.readingTime} read</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -4,61 +4,57 @@ import { getDictionary } from '@/dictionaries';
|
|||
|
||||
const Partners = async ({ lang }) => {
|
||||
const dictionary = await getDictionary(lang);
|
||||
const sponsorLogos = ['logo-1', 'logo-2', 'logo-3', 'logo-4', 'logo-5'];
|
||||
const mediaPartnerLogos = ['logo-1', 'logo-2', 'logo-3', 'logo-4', 'logo-5'];
|
||||
|
||||
console.log(lang);
|
||||
const getShuffledLogos = (logos) => {
|
||||
for (let i = logos.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
|
||||
[logos[i], logos[j]] = [logos[j], logos[i]];
|
||||
}
|
||||
return logos;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='my-14'>
|
||||
<div className='lg:py-22 mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8'>
|
||||
<p className='text-center text-base font-semibold uppercase tracking-wider text-gray-600'>
|
||||
<section>
|
||||
<div className='container flex flex-col gap-8 sm:gap-12'>
|
||||
<div>
|
||||
<h2 className='pb-4 text-center text-2xl text-blue-2 sm:pb-8 sm:text-4xl'>
|
||||
{dictionary.main.partners.sponsors}
|
||||
</h2>
|
||||
<div className='flex flex-wrap justify-evenly gap-6'>
|
||||
{getShuffledLogos(sponsorLogos).map((logo) => {
|
||||
return (
|
||||
<div
|
||||
key={logo}
|
||||
className='cursor-pointer opacity-50 hover:opacity-100'
|
||||
>
|
||||
<p>{logo}</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2 className='pb-4 text-center text-2xl text-blue-2 sm:pb-8 sm:text-4xl'>
|
||||
{dictionary.main.partners.media}
|
||||
</p>
|
||||
<div className='mt-6 grid grid-cols-2 gap-0.5 md:grid-cols-3 lg:mt-12'>
|
||||
<div className='col-span-1 flex justify-center bg-gray-50 px-8 py-8'>
|
||||
<Image
|
||||
className='max-h-12'
|
||||
src='https://tailwindui.com/img/logos/transistor-logo-gray-400.svg'
|
||||
alt='Workcation'
|
||||
/>
|
||||
</div>
|
||||
<div className='col-span-1 flex justify-center bg-gray-50 px-8 py-8'>
|
||||
<Image
|
||||
className='max-h-12'
|
||||
src='https://tailwindui.com/img/logos/mirage-logo-gray-400.svg'
|
||||
alt='Mirage'
|
||||
/>
|
||||
</div>
|
||||
<div className='col-span-1 flex justify-center bg-gray-50 px-8 py-8'>
|
||||
<Image
|
||||
className='max-h-12'
|
||||
src='https://tailwindui.com/img/logos/tuple-logo-gray-400.svg'
|
||||
alt='Tuple'
|
||||
/>
|
||||
</div>
|
||||
<div className='col-span-1 flex justify-center bg-gray-50 px-8 py-8'>
|
||||
<Image
|
||||
className='max-h-12'
|
||||
src='https://tailwindui.com/img/logos/laravel-logo-gray-400.svg'
|
||||
alt='Laravel'
|
||||
/>
|
||||
</div>
|
||||
<div className='col-span-1 flex justify-center bg-gray-50 px-8 py-8'>
|
||||
<Image
|
||||
className='max-h-12'
|
||||
src='https://tailwindui.com/img/logos/statickit-logo-gray-400.svg'
|
||||
alt='StaticKit'
|
||||
/>
|
||||
</div>
|
||||
<div className='col-span-1 flex justify-center bg-gray-50 px-8 py-8'>
|
||||
<Image
|
||||
className='max-h-12'
|
||||
src='https://tailwindui.com/img/logos/statamic-logo-gray-400.svg'
|
||||
alt='Statamic'
|
||||
/>
|
||||
</h2>
|
||||
<div className='flex flex-wrap justify-evenly gap-6'>
|
||||
{getShuffledLogos(mediaPartnerLogos).map((logo) => {
|
||||
return (
|
||||
<div
|
||||
key={logo}
|
||||
className='cursor-pointer opacity-50 hover:opacity-100'
|
||||
>
|
||||
<p>{logo}</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import { i18n } from '../../i18n-config';
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import matter from 'gray-matter';
|
||||
import process from 'process';
|
||||
|
||||
async function getTruncatedPostContent(content) {
|
||||
const words = content.split(' ');
|
||||
|
@ -51,9 +52,7 @@ export const getSortedPostsData = cache(async (locale) => {
|
|||
}
|
||||
});
|
||||
|
||||
return {
|
||||
posts: sortedPostsData,
|
||||
};
|
||||
return sortedPostsData;
|
||||
});
|
||||
|
||||
export const getAllPosts = cache(async () => {
|
||||
|
|
|
@ -28,15 +28,16 @@ export function middleware(request: NextRequest) {
|
|||
const pathname = request.nextUrl.pathname;
|
||||
// `/_next/` and `/api/` are ignored by the watcher, but we need to ignore files in `public` manually.
|
||||
// If you have one
|
||||
if (
|
||||
[
|
||||
const paths = [
|
||||
'/manifest.json',
|
||||
'/favicon.ico',
|
||||
'/next.svg',
|
||||
'/vercel.svg',
|
||||
// Your other files in `public`
|
||||
].includes(pathname)
|
||||
)
|
||||
];
|
||||
const dirs = ['/images/', '/posts/'];
|
||||
|
||||
if (paths.includes(pathname) || dirs.some((dir) => pathname.startsWith(dir)))
|
||||
return;
|
||||
|
||||
// Check if there is any supported locale in the pathname
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
title: 'Bulgarian'
|
||||
date: '08-06-2024'
|
||||
imageUrl: '/posts/post-1.webp'
|
||||
---
|
||||
|
||||
**Some** description
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
title: 'English'
|
||||
date: '08-06-2024'
|
||||
imageUrl: '/posts/post-1.webp'
|
||||
---
|
||||
|
||||
**Some** description
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap');
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
.container {
|
||||
@apply mx-auto w-full max-w-screen-xl px-6 py-8 sm:px-12 sm:py-10;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
p {
|
||||
@apply text-black;
|
||||
|
|
|
@ -4,17 +4,23 @@ const config: Config = {
|
|||
content: ['./src/**/*.{js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
openSans: ['Open Sans', 'sans-serif'],
|
||||
},
|
||||
backgroundImage: {
|
||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||
'gradient-conic':
|
||||
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
|
||||
'home-bg': "url('/images/openfest-1.webp')",
|
||||
},
|
||||
colors: {
|
||||
'dark-blue': '#09021B',
|
||||
'deep-blue': '#0F0429',
|
||||
blue: '#2F1B5D',
|
||||
'neon-green': '#34EAD8',
|
||||
'neon-pink': '#D92ACE',
|
||||
'blue-2': '#004394',
|
||||
'blue-8': '#E2EFFE',
|
||||
//'dark-blue': '#09021B',
|
||||
//'deep-blue': '#0F0429',
|
||||
//blue: '#2F1B5D',
|
||||
//'neon-green': '#34EAD8',
|
||||
//'neon-pink': '#D92ACE',
|
||||
},
|
||||
letterSpacing: {
|
||||
max: '0.3em',
|
||||
|
|
Loading…
Reference in New Issue