Add new home page
This commit is contained in:
parent
9b090d212a
commit
d668093240
|
@ -7,7 +7,7 @@
|
||||||
"contact": "Контакти"
|
"contact": "Контакти"
|
||||||
},
|
},
|
||||||
"main": {
|
"main": {
|
||||||
"date": "2-ри – 3-ти",
|
"date": "2 – 3",
|
||||||
"monthYear": "Ноември 2024",
|
"monthYear": "Ноември 2024",
|
||||||
"titleLocation": "Иновативен форум \"Джон Атанасов\" – София Тех Парк",
|
"titleLocation": "Иновативен форум \"Джон Атанасов\" – София Тех Парк",
|
||||||
"countdownTimer": {
|
"countdownTimer": {
|
||||||
|
@ -26,6 +26,11 @@
|
||||||
"volunteers": "Присъединете се като доброволец",
|
"volunteers": "Присъединете се като доброволец",
|
||||||
"partners": "Подкрепете събитието като партньор"
|
"partners": "Подкрепете събитието като партньор"
|
||||||
},
|
},
|
||||||
|
"news": {
|
||||||
|
"title": "Новини",
|
||||||
|
"cardButton": "Прочети",
|
||||||
|
"button": "Виж всички"
|
||||||
|
},
|
||||||
"partners": {
|
"partners": {
|
||||||
"sponsors": "Sponsors",
|
"sponsors": "Sponsors",
|
||||||
"media": "Media partners"
|
"media": "Media partners"
|
||||||
|
|
|
@ -8,24 +8,29 @@
|
||||||
},
|
},
|
||||||
"main": {
|
"main": {
|
||||||
"date": "2 - 3",
|
"date": "2 - 3",
|
||||||
"monthYear": "November 2024",
|
"monthYear": "November, 2024",
|
||||||
"titleLocation": "Innovation forum \"John Atanasoff\" – Sofia Tech Park",
|
"titleLocation": "Innovation forum \"John Atanasoff\" – Sofia Tech Park",
|
||||||
"countdownTimer": {
|
"countdownTimer": {
|
||||||
"title": "Until OpenFest remain:",
|
"title": "OpenFest starts in:",
|
||||||
"days": "Days",
|
"days": "Days",
|
||||||
"hours": "Hours",
|
"hours": "Hours",
|
||||||
"minutes": "Minutes"
|
"minutes": "Minutes"
|
||||||
},
|
},
|
||||||
"description": {
|
"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."
|
"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": {
|
"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",
|
"lecture": "Take part with a lecture, a workshop or a booth",
|
||||||
"volunteers": "Join us as a volunteer",
|
"volunteers": "Join us as a volunteer",
|
||||||
"partners": "Support the event as a partner"
|
"partners": "Support the event as a partner"
|
||||||
},
|
},
|
||||||
|
"news": {
|
||||||
|
"title": "News",
|
||||||
|
"cardButton": "Read",
|
||||||
|
"button": "See all"
|
||||||
|
},
|
||||||
"partners": {
|
"partners": {
|
||||||
"sponsors": "Sponsors",
|
"sponsors": "Sponsors",
|
||||||
"media": "Media partners"
|
"media": "Media partners"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -30,7 +30,7 @@
|
||||||
"@types/react": "^18.3.5",
|
"@types/react": "^18.3.5",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^9.10.0",
|
||||||
"eslint-config-next": "^14.2.8",
|
"eslint-config-next": "^14.2.8",
|
||||||
"install": "^0.13.0",
|
"install": "^0.13.0",
|
||||||
"npm": "^10.8.3",
|
"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 { i18n } from '../../../i18n-config';
|
||||||
|
|
||||||
import NavBar from '@/components/NavBar';
|
import NavBar from '../../components/NavBar';
|
||||||
import Footer from '@/components/Footer';
|
import Footer from '@/components/Footer';
|
||||||
|
|
||||||
import '@/styles/globals.css';
|
import '@/styles/globals.css';
|
||||||
|
@ -10,8 +9,6 @@ export async function generateStaticParams() {
|
||||||
return i18n.locales.map((locale) => ({ lang: locale }));
|
return i18n.locales.map((locale) => ({ lang: locale }));
|
||||||
}
|
}
|
||||||
|
|
||||||
const inter = Inter({ subsets: ['latin'] });
|
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
title: 'OpenFest 2024',
|
title: 'OpenFest 2024',
|
||||||
description: 'Да се видим на OpenFest 2024!',
|
description: 'Да се видим на OpenFest 2024!',
|
||||||
|
@ -21,12 +18,12 @@ export default function RootLayout({ children, params }) {
|
||||||
return (
|
return (
|
||||||
<html lang={params.lang}>
|
<html lang={params.lang}>
|
||||||
<body
|
<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>
|
<header>
|
||||||
<NavBar lang={params.lang} />
|
<NavBar lang={params.lang} />
|
||||||
</header>
|
</header>
|
||||||
{children}
|
<main>{children}</main>
|
||||||
<Footer lang={params.lang} />
|
<Footer lang={params.lang} />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,104 +1,88 @@
|
||||||
import CountDownTimer from '@/components/CountDownTimer';
|
import CountDownTimer from '@/components/CountDownTimer';
|
||||||
import NewsFeed from '@/components/NewsFeed';
|
import NewsFeed from '@/components/NewsFeed';
|
||||||
import Partners from '@/components/Partners';
|
import Partners from '@/components/Partners';
|
||||||
// import { getSortedPostsData } from '../../lib/posts';
|
import Image from 'next/image';
|
||||||
import { getDictionary } from '@/dictionaries';
|
import { getDictionary } from '@/dictionaries';
|
||||||
|
|
||||||
export default async function Home({ params }) {
|
export default async function Home({ params }) {
|
||||||
const { lang } = params;
|
const { lang } = params;
|
||||||
const dictionary = await getDictionary(lang);
|
const dictionary = await getDictionary(lang);
|
||||||
// const { posts } = await getSortedPostsData(lang);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<section>
|
<section className='h-[65vh] bg-home-bg bg-cover sm:h-[75vh]'>
|
||||||
<div className='bg-gradient-to-r from-sky-500 to-indigo-500'>
|
<div className='container flex h-full flex-col justify-center gap-10 text-black sm:gap-16'>
|
||||||
<div className='mx-auto max-w-2xl py-32 sm:py-48 lg:py-56'>
|
|
||||||
<div className='text-center'>
|
<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}
|
{dictionary.main.date}
|
||||||
</h1>
|
</h1>
|
||||||
<h2 className='text-gray-900'>{dictionary.main.monthYear}</h2>
|
</div>
|
||||||
<p className='mt-6 text-lg leading-8 text-gray-600'>
|
<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}
|
{dictionary.main.titleLocation}
|
||||||
</p>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<CountDownTimer props={dictionary.main.countdownTimer} />
|
<CountDownTimer props={dictionary.main.countdownTimer} />
|
||||||
|
<section className='bg-blue-8'>
|
||||||
<section className='bg-[#E2EFFE] px-24 py-12'>
|
<div className='container flex flex-col gap-4 sm:gap-8'>
|
||||||
<h2 className='pb-16 text-center text-[2.2rem] text-[#004394]'>
|
<h2 className='text-center text-2xl text-blue-2 sm:text-4xl'>
|
||||||
{dictionary.main.description.title}
|
{dictionary.main.description.title}
|
||||||
</h2>
|
</h2>
|
||||||
<div className='flex-col md:flex md:flex-row'>
|
<div className='flex flex-col gap-6 sm:flex-row'>
|
||||||
<div className='mx-2 text-center text-[#004394]'>
|
<div className='flex-1'>
|
||||||
{dictionary.main.description.text}
|
<p> {dictionary.main.description.text}</p>
|
||||||
|
</div>
|
||||||
|
<div className='flex-1'>
|
||||||
|
<Image
|
||||||
|
src='/images/openfest-2.webp'
|
||||||
|
width='620'
|
||||||
|
height='380'
|
||||||
|
></Image>
|
||||||
</div>
|
</div>
|
||||||
<div className='mx-2 text-center text-[#004394]'>
|
|
||||||
{dictionary.main.description.text}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<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}
|
{dictionary.main.cfp.title}
|
||||||
</h2>
|
</h2>
|
||||||
{/* <dl className='mt-5 grid grid-cols-1 gap-5 sm:grid-cols-3'> */}
|
<div className='flex flex-col gap-4 sm:flex-row sm:gap-8'>
|
||||||
<dl className='mt-5 grid grid-cols-1 place-items-center gap-1 sm:grid-cols-3'>
|
<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='max-w-[350px] overflow-hidden rounded-lg bg-[#004394] px-4 py-5 text-center shadow sm:p-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'>
|
||||||
<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]'>
|
|
||||||
<i className='fa-solid fa-lightbulb'></i>
|
<i className='fa-solid fa-lightbulb'></i>
|
||||||
</div>
|
</div>
|
||||||
</dt>
|
<p className='text-center text-white'>
|
||||||
<dd className='mt-1 text-[22px] font-semibold text-[#F2F5F9]'>
|
|
||||||
{dictionary.main.cfp.lecture}
|
{dictionary.main.cfp.lecture}
|
||||||
</dd>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className='max-w-[350px] overflow-hidden rounded-lg bg-[#004394] px-4 py-5 text-center shadow sm:p-6'>
|
<div className='flex basis-1/3 flex-col items-center justify-center gap-3 rounded-xl bg-blue-2 p-6 sm:gap-6'>
|
||||||
<dt className='truncate text-sm font-medium text-[#004394]'>
|
<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'>
|
||||||
<div className='m-auto mb-2 flex h-20 w-20 items-center justify-center rounded-full bg-[#C8E0FC] text-[2.3rem]'>
|
|
||||||
<i className='fa-solid fa-helmet-safety'></i>
|
<i className='fa-solid fa-helmet-safety'></i>
|
||||||
</div>
|
</div>
|
||||||
</dt>
|
<p className='text-center text-white'>
|
||||||
<dd className='mt-1 text-[22px] font-semibold text-[#F2F5F9]'>
|
|
||||||
{dictionary.main.cfp.volunteers}
|
{dictionary.main.cfp.volunteers}
|
||||||
</dd>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className='max-w-[350px] overflow-hidden rounded-lg bg-[#004394] px-4 py-6 text-center shadow sm:p-6'>
|
<div className='flex basis-1/3 flex-col items-center justify-center gap-3 rounded-xl bg-blue-2 p-6 sm:gap-6'>
|
||||||
<dt className='truncate text-sm font-medium text-[#004394]'>
|
<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'>
|
||||||
<div className='m-auto mb-2 flex h-20 w-20 items-center justify-center rounded-full bg-[#C8E0FC] text-[2.3rem]'>
|
|
||||||
<i className='fa-solid fa-handshake-angle'></i>
|
<i className='fa-solid fa-handshake-angle'></i>
|
||||||
</div>
|
</div>
|
||||||
</dt>
|
<p className='text-center text-white'>
|
||||||
<dd className='mt-1 text-[22px] font-semibold text-[#F2F5F9]'>
|
|
||||||
{dictionary.main.cfp.partners}
|
{dictionary.main.cfp.partners}
|
||||||
</dd>
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
|
||||||
</section>
|
</section>
|
||||||
<main>
|
<NewsFeed lang={lang} />
|
||||||
<NewsFeed />
|
<Partners lang={lang} />
|
||||||
<Partners props={lang} />
|
|
||||||
</main>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,9 @@ const CountDownTimer = ({ props }) => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const targetDate = new Date('2024-11-02T09:30:00+03:00');
|
const targetDate = new Date('2024-11-02T09:30:00+03:00');
|
||||||
|
const countDownIntervalTime = 1000;
|
||||||
|
|
||||||
const interval = setInterval(() => {
|
const updateCountDown = () => {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
||||||
const diff = targetDate.getTime() - now.getTime();
|
const diff = targetDate.getTime() - now.getTime();
|
||||||
|
@ -22,54 +23,69 @@ const CountDownTimer = ({ props }) => {
|
||||||
|
|
||||||
const m = Math.floor((diff / (1000 * 60)) % 60);
|
const m = Math.floor((diff / (1000 * 60)) % 60);
|
||||||
setMinutes(m);
|
setMinutes(m);
|
||||||
}, 1000);
|
};
|
||||||
|
|
||||||
|
// Set time
|
||||||
|
updateCountDown();
|
||||||
|
|
||||||
|
// Set interval
|
||||||
|
const interval = setInterval(updateCountDown, countDownIntervalTime);
|
||||||
|
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className='m-12 mb-20 pt-6'>
|
<section>
|
||||||
{/* <span className='mb-12 mt-4 block text-3xl text-black'>
|
<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}
|
{props.title}
|
||||||
</span> */}
|
</h2>
|
||||||
<div className='flex justify-evenly'>
|
<div className='flex flex-col items-center justify-evenly gap-8 lg:flex-row'>
|
||||||
<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 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'></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-1/2 bg-[#C8E0FC]'></div>
|
||||||
</div>
|
</div>
|
||||||
<div className='absolute inset-0 flex items-center justify-center'>
|
<div className='absolute inset-0 flex items-center justify-center'>
|
||||||
<span className='text-center font-bold text-gray-800'>
|
<span className='text-center font-bold text-gray-800'>
|
||||||
<p className='pb-[38px] pt-[14px] text-[85px]'>{days}</p>
|
<p className='pb-1 pt-2 text-5xl lg:pb-3 lg:pt-4 lg:text-8xl'>
|
||||||
<p className='text-[36px] font-light'> {props.days}</p>
|
{days}
|
||||||
|
</p>
|
||||||
|
<p className='text-xl font-light lg:text-5xl'> {props.days}</p>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</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 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-full'></div>
|
||||||
<div className='absolute left-0 top-0 h-full w-1/2 bg-[#C8E0FC]'></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className='absolute inset-0 flex items-center justify-center'>
|
<div className='absolute inset-0 flex items-center justify-center'>
|
||||||
<span className='text-center font-bold text-gray-800'>
|
<span className='text-center font-bold text-gray-800'>
|
||||||
<p className='pb-[38px] pt-[14px] text-[85px]'>{hours}</p>
|
<p className='pb-1 pt-2 text-5xl lg:pb-3 lg:pt-4 lg:text-8xl'>
|
||||||
<p className='text-[36px] font-light'> {props.hours}</p>
|
{hours}
|
||||||
|
</p>
|
||||||
|
<p className='text-xl font-light lg:text-5xl'> {props.hours}</p>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</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 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'></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>
|
||||||
<div className='absolute inset-0 flex items-center justify-center'>
|
<div className='absolute inset-0 flex items-center justify-center'>
|
||||||
<span className='text-center font-bold text-gray-800'>
|
<span className='text-center font-bold text-gray-800'>
|
||||||
<p className='pb-[38px] pt-[14px] text-[85px]'>{minutes}</p>
|
<p className='pb-1 pt-2 text-5xl lg:pb-3 lg:pt-4 lg:text-8xl'>
|
||||||
<p className='text-[36px] font-light'> {props.minutes}</p>
|
{minutes}
|
||||||
|
</p>
|
||||||
|
<p className='text-xl font-light lg:text-5xl'>
|
||||||
|
{props.minutes}
|
||||||
|
</p>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,40 +35,14 @@ const Navbar = async ({ lang }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<nav className='my-6 bg-white'>
|
<nav className='container flex flex-col items-center justify-between gap-4 bg-white text-black sm:flex-row'>
|
||||||
<div className='mx-auto flex max-w-screen-xl flex-wrap items-center justify-between p-4'>
|
<div>
|
||||||
<a
|
<a href='https://openfest.org/' className='flex items-center'>
|
||||||
href='https://openfest.org/'
|
|
||||||
className='flex items-center space-x-3 rtl:space-x-reverse'
|
|
||||||
>
|
|
||||||
<Image src={OpenFestLogo} alt='OpenFest Logo' width={256} />
|
<Image src={OpenFestLogo} alt='OpenFest Logo' width={256} />
|
||||||
</a>
|
</a>
|
||||||
{/* <button
|
</div>
|
||||||
data-collapse-toggle='navbar-default'
|
<div className='flex items-center justify-center'>
|
||||||
type='button'
|
<ul className='flex flex-wrap items-center justify-center gap-4 sm:gap-8'>
|
||||||
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'>
|
|
||||||
<li>
|
<li>
|
||||||
<a href='#' className='' aria-current='page'>
|
<a href='#' className='' aria-current='page'>
|
||||||
{dictionary.nav.home}
|
{dictionary.nav.home}
|
||||||
|
@ -99,7 +73,15 @@ const Navbar = async ({ lang }) => {
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</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>
|
</nav>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,137 +1,50 @@
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
|
import { getDictionary } from '@/dictionaries';
|
||||||
|
import { getSortedPostsData } from '@/lib/posts';
|
||||||
|
|
||||||
const posts = [
|
const NewsFeed = async ({ lang }) => {
|
||||||
{
|
const dictionary = await getDictionary(lang);
|
||||||
title: 'Boost your conversion rate',
|
const posts = await getSortedPostsData(lang);
|
||||||
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 = () => {
|
|
||||||
return (
|
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'>
|
<section className='bg-blue-8'>
|
||||||
<div className='absolute inset-0'>
|
<div className='container flex flex-col gap-4 sm:gap-8'>
|
||||||
<div className='h-1/3 bg-white sm:h-2/3' />
|
<h2 className='text-center text-2xl text-blue-2 sm:text-start sm:text-4xl'>
|
||||||
</div>
|
{dictionary.main.news.title}
|
||||||
<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
|
|
||||||
</h2>
|
</h2>
|
||||||
<p className='mx-auto mt-3 max-w-2xl text-xl text-gray-500 sm:mt-4'>
|
<div className='flex flex-col gap-4 sm:flex-row sm:gap-8'>
|
||||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ipsa
|
{posts.map((post) => {
|
||||||
libero labore natus atque, ducimus sed.
|
return (
|
||||||
</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
|
<div
|
||||||
key={post.title}
|
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'>
|
<div>
|
||||||
<Image
|
<Image src={post.imageUrl} width='400' height='190'></Image>
|
||||||
className='h-48 w-full object-cover'
|
|
||||||
src={post.imageUrl}
|
|
||||||
alt=''
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className='flex flex-1 flex-col justify-between bg-white p-6'>
|
<div className='flex h-full flex-1 flex-col gap-2 bg-white p-6 text-center sm:gap-4'>
|
||||||
<div className='flex-1'>
|
<p className='text-blue-2'>{post.title}</p>
|
||||||
<p className='text-sm font-medium text-indigo-600'>
|
<p className='text-sm opacity-50'>{post.date}</p>
|
||||||
<a href={post.category.href} className='hover:underline'>
|
<a
|
||||||
{post.category.name}
|
href='#'
|
||||||
</a>
|
className='mx-auto mt-auto self-baseline rounded-3xl bg-blue-2 px-12 py-2'
|
||||||
</p>
|
>
|
||||||
<a href={post.href} className='mt-2 block'>
|
{dictionary.main.news.cardButton}
|
||||||
<p className='text-xl font-semibold text-gray-900'>
|
|
||||||
{post.title}
|
|
||||||
</p>
|
|
||||||
<p className='mt-3 text-base text-gray-500'>
|
|
||||||
{post.description}
|
|
||||||
</p>
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div className='mt-6 flex items-center'>
|
</div>
|
||||||
<div className='flex-shrink-0'>
|
);
|
||||||
<a href={post.author.href}>
|
})}
|
||||||
<span className='sr-only'>{post.author.name}</span>
|
</div>
|
||||||
<Image
|
<a
|
||||||
className='h-10 w-10 rounded-full'
|
href='#'
|
||||||
src={post.author.imageUrl}
|
className='mt-4 flex items-center justify-center gap-4 self-center rounded-3xl bg-blue-2 px-12 py-2 sm:self-baseline'
|
||||||
alt=''
|
>
|
||||||
/>
|
{dictionary.main.news.button}
|
||||||
|
<i className='fa-solid fa-arrow-right'></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div className='ml-3'>
|
</section>
|
||||||
<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>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,61 +4,57 @@ import { getDictionary } from '@/dictionaries';
|
||||||
|
|
||||||
const Partners = async ({ lang }) => {
|
const Partners = async ({ lang }) => {
|
||||||
const dictionary = await getDictionary(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 (
|
return (
|
||||||
<div className='my-14'>
|
<section>
|
||||||
<div className='lg:py-22 mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8'>
|
<div className='container flex flex-col gap-8 sm:gap-12'>
|
||||||
<p className='text-center text-base font-semibold uppercase tracking-wider text-gray-600'>
|
<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}
|
{dictionary.main.partners.media}
|
||||||
</p>
|
</h2>
|
||||||
<div className='mt-6 grid grid-cols-2 gap-0.5 md:grid-cols-3 lg:mt-12'>
|
<div className='flex flex-wrap justify-evenly gap-6'>
|
||||||
<div className='col-span-1 flex justify-center bg-gray-50 px-8 py-8'>
|
{getShuffledLogos(mediaPartnerLogos).map((logo) => {
|
||||||
<Image
|
return (
|
||||||
className='max-h-12'
|
<div
|
||||||
src='https://tailwindui.com/img/logos/transistor-logo-gray-400.svg'
|
key={logo}
|
||||||
alt='Workcation'
|
className='cursor-pointer opacity-50 hover:opacity-100'
|
||||||
/>
|
>
|
||||||
</div>
|
<p>{logo}</p>
|
||||||
<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'
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { i18n } from '../../i18n-config';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import matter from 'gray-matter';
|
import matter from 'gray-matter';
|
||||||
|
import process from 'process';
|
||||||
|
|
||||||
async function getTruncatedPostContent(content) {
|
async function getTruncatedPostContent(content) {
|
||||||
const words = content.split(' ');
|
const words = content.split(' ');
|
||||||
|
@ -51,9 +52,7 @@ export const getSortedPostsData = cache(async (locale) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return sortedPostsData;
|
||||||
posts: sortedPostsData,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getAllPosts = cache(async () => {
|
export const getAllPosts = cache(async () => {
|
||||||
|
|
|
@ -28,15 +28,16 @@ export function middleware(request: NextRequest) {
|
||||||
const pathname = request.nextUrl.pathname;
|
const pathname = request.nextUrl.pathname;
|
||||||
// `/_next/` and `/api/` are ignored by the watcher, but we need to ignore files in `public` manually.
|
// `/_next/` and `/api/` are ignored by the watcher, but we need to ignore files in `public` manually.
|
||||||
// If you have one
|
// If you have one
|
||||||
if (
|
const paths = [
|
||||||
[
|
|
||||||
'/manifest.json',
|
'/manifest.json',
|
||||||
'/favicon.ico',
|
'/favicon.ico',
|
||||||
'/next.svg',
|
'/next.svg',
|
||||||
'/vercel.svg',
|
'/vercel.svg',
|
||||||
// Your other files in `public`
|
// Your other files in `public`
|
||||||
].includes(pathname)
|
];
|
||||||
)
|
const dirs = ['/images/', '/posts/'];
|
||||||
|
|
||||||
|
if (paths.includes(pathname) || dirs.some((dir) => pathname.startsWith(dir)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check if there is any supported locale in the pathname
|
// Check if there is any supported locale in the pathname
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
title: 'Bulgarian'
|
title: 'Bulgarian'
|
||||||
date: '08-06-2024'
|
date: '08-06-2024'
|
||||||
|
imageUrl: '/posts/post-1.webp'
|
||||||
---
|
---
|
||||||
|
|
||||||
**Some** description
|
**Some** description
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
title: 'English'
|
title: 'English'
|
||||||
date: '08-06-2024'
|
date: '08-06-2024'
|
||||||
|
imageUrl: '/posts/post-1.webp'
|
||||||
---
|
---
|
||||||
|
|
||||||
**Some** description
|
**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://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 base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
.container {
|
||||||
|
@apply mx-auto w-full max-w-screen-xl px-6 py-8 sm:px-12 sm:py-10;
|
||||||
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
p {
|
p {
|
||||||
@apply text-black;
|
@apply text-black;
|
||||||
|
|
|
@ -4,17 +4,23 @@ const config: Config = {
|
||||||
content: ['./src/**/*.{js,ts,jsx,tsx}'],
|
content: ['./src/**/*.{js,ts,jsx,tsx}'],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
|
fontFamily: {
|
||||||
|
openSans: ['Open Sans', 'sans-serif'],
|
||||||
|
},
|
||||||
backgroundImage: {
|
backgroundImage: {
|
||||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||||
'gradient-conic':
|
'gradient-conic':
|
||||||
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
|
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
|
||||||
|
'home-bg': "url('/images/openfest-1.webp')",
|
||||||
},
|
},
|
||||||
colors: {
|
colors: {
|
||||||
'dark-blue': '#09021B',
|
'blue-2': '#004394',
|
||||||
'deep-blue': '#0F0429',
|
'blue-8': '#E2EFFE',
|
||||||
blue: '#2F1B5D',
|
//'dark-blue': '#09021B',
|
||||||
'neon-green': '#34EAD8',
|
//'deep-blue': '#0F0429',
|
||||||
'neon-pink': '#D92ACE',
|
//blue: '#2F1B5D',
|
||||||
|
//'neon-green': '#34EAD8',
|
||||||
|
//'neon-pink': '#D92ACE',
|
||||||
},
|
},
|
||||||
letterSpacing: {
|
letterSpacing: {
|
||||||
max: '0.3em',
|
max: '0.3em',
|
||||||
|
|
Loading…
Reference in New Issue