23 Commits

Author SHA1 Message Date
Rene Arumetsa
aafc2421cf Changes to footer, correct contact info 2026-05-01 14:51:22 +03:00
Rene Arumetsa
e278d7bd25 Right sponsors 2026-05-01 14:37:40 +03:00
Rene Arumetsa
c177ca1040 Changes in teaser carosel text 2026-05-01 11:36:27 +03:00
Rene Arumetsa
0b42131690 Make sponsors into a carosel 2026-05-01 11:25:16 +03:00
Rene Arumetsa
c5bff17388 Some changes in main page 2026-05-01 11:17:36 +03:00
Renkar
403ff6adfb Merge pull request #116 from Lapikud/landing-2026
Landing 2026
2026-04-30 17:43:08 +03:00
Renkar
254cf8ef2c Merge branch 'development' into landing-2026 2026-04-30 17:36:23 +03:00
Rene Arumetsa
00196034a3 Remove prizes from slides 2026-04-30 16:31:54 +03:00
Rene Arumetsa
fe8fbf3024 Carosel slide every 5s 2026-04-30 16:28:19 +03:00
Rene Arumetsa
cbe85064f6 Fix slides, positioning 2026-04-30 16:24:37 +03:00
Rene Arumetsa
81de01fab8 Add hero pictures in teasre carosel 2026-04-30 16:18:53 +03:00
Rene Arumetsa
d20cdc6b98 Add very basic teasercarousel 2026-04-30 16:13:32 +03:00
Rene Arumetsa
be3a75752b Fix various texts 2026-04-30 16:09:18 +03:00
Rene Arumetsa
0b6d2ce661 Fix section sizes 2026-04-30 15:56:09 +03:00
Rene Arumetsa
74eee5a30d Fix text coloring 2026-04-30 15:51:11 +03:00
Rene Arumetsa
0ece12898f Move "come to.." text inside teaser section" 2026-04-30 15:44:13 +03:00
Rene Arumetsa
9bdadb2501 Rough first patch 2026-04-30 15:41:24 +03:00
Arto Reinik
8d4575ef3e frontend: add one more picture for fienta 2026-03-31 09:49:25 +03:00
Renkar
02dbff37c7 Merge pull request #108 from Lapikud/main
up_to_date with main
2026-03-29 20:40:57 +03:00
Renkar
0f3c7dc1d3 Merge pull request #107 from Lapikud/development
add pictures for fienta
2026-03-29 18:10:58 +03:00
TFT
3e542b3544 add banner image 2026-03-29 18:08:47 +03:00
TFT
1c1370251c add pictures for fienta 2026-03-29 16:38:08 +03:00
Renkar
f653c3d59f Merge pull request #106 from Lapikud/development
Disc invite link
2026-03-09 09:15:52 +02:00
23 changed files with 463 additions and 398 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1024 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -1,8 +1,9 @@
import { vipnagorgialla } from "@/components/Vipnagorgialla";
import Sponsors from "@/components/Sponsors";
import HeroSection from "@/components/HeroSection";
import TeaserCarousel from "@/components/TeaserCarousel";
import { Link } from "@/i18n/routing";
import { getTranslations, setRequestLocale } from "next-intl/server";
import Image from "next/image";
export default async function Home({
params,
@@ -15,58 +16,22 @@ export default async function Home({
return (
<div>
{/* Title */}
<div className="border-b-3 border-[#1F5673] grid grid-cols-1 md:grid-cols-[2fr_1fr] items-center justify-between mt-18 gap-12 py-8">
<Image
src="/tipilan-white.svg"
width={850}
height={120}
alt="TipiLAN Logo"
className="px-8 py-8 md:px-12 md:py-14 dark:hidden w-[max(300px,min(100%,850px))] h-auto"
/>
<Image
src="/tipilan-dark.svg"
width={850}
height={120}
alt="TipiLAN Logo"
className="px-8 py-8 md:px-12 md:py-14 not-dark:hidden w-[max(300px,min(100%,850px))] h-auto2"
/>
<div className="pr-12 hidden md:block text-right">
<h3
className={`text-[clamp(1.25rem,0.75rem+2.5vw,3.75rem)] ${vipnagorgialla.className} leading-[90%] font-bold italic uppercase dark:text-[#EEE5E5] text-[#2A2C3F]`}
>
{t("tournaments.prizePool")}
</h3>
<h2
className={`text-[clamp(2rem,1.2rem+4vw,6rem)] ${vipnagorgialla.className} leading-[90%] font-bold italic text-[#007CAB] dark:text-[#00A3E0]`}
>
10 000
</h2>
</div>
{/* Hero */}
<div className="mt-18">
<HeroSection />
</div>
{/* Farewell message */}
<div>
<section
className={`p-8 md:p-12 flex flex-col ${vipnagorgialla.className} font-bold italic border-b-3 border-[#1F5673] hover:bg-[#007CAB] dark:hover:bg-[#00A3E0] group transition`}
>
<h2 className="text-[clamp(2rem,1.5rem+0.5vw,3rem)] text-[#007CAB] dark:text-[#00A3E0] dark:group-hover:text-[#EEE5E5] group-hover:text-[#EEE5E5]">
{t("home.sections.farewellMessage")} <span className="not-italic">🩵</span>
</h2>
</section>
</div>
{/* Grid of buttons */}
<div className="grid grid-cols-1 xl:grid-cols-3 border-[#1F5673]">
{/* Nav cards: Piletid + Turniirid */}
<div className="grid grid-cols-1 md:grid-cols-2 md:h-[260px] border-b-3 border-[#1F5673]">
<Link
href="/ajakava"
className="px-8 md:px-12 py-8 flex flex-col gap-4 border-b-3 lg:border-r-3 group border-[#1F5673] hover:bg-[#007CAB] dark:hover:bg-[#00A3E0] transition"
href="/piletid"
className="px-8 md:px-12 py-8 flex flex-col justify-center gap-4 border-b-3 md:border-b-0 md:border-r-3 group border-[#1F5673] hover:bg-[#007CAB] dark:hover:bg-[#00A3E0] transition"
>
<div className="cursor-pointer flex flex-row justify-between gap-4 items-center">
<div className="flex flex-row justify-between gap-4 items-center">
<h2
className={`text-[clamp(2rem,1.8rem+1vw,3rem)] ${vipnagorgialla.className} font-bold italic uppercase dark:text-[#EEE5E5] text-[#2A2C3F] group-hover:text-black dark:group-hover:text-[#2A2C3F]`}
>
{t("navigation.schedule")}
{t("navigation.tickets")}
</h2>
<span className="material-symbols-outlined !text-[clamp(2rem,1.5rem+1.5vw,3.5rem)] !font-bold text-[#007CAB] dark:text-[#00A3E0] group-hover:translate-x-2 dark:group-hover:text-[#EEE5E5] group-hover:text-[#EEE5E5] transition">
arrow_right_alt
@@ -74,20 +39,18 @@ export default async function Home({
</div>
<div className="flex flex-col gap-4">
<span className="material-symbols-outlined !text-[clamp(2rem,1.5rem+1.5vw,3.5rem)] text-[#007CAB] dark:text-[#00A3E0] dark:group-hover:text-[#EEE5E5] group-hover:text-[#EEE5E5]">
event_note
confirmation_number
</span>
<p className="text-[clamp(0.875rem,0.75rem+0.5vw,1.25rem)] tracking-[-0.045rem] dark:group-hover:text-[#2A2C3F] group-hover:text-black">
{t("home.sections.schedule.description")}
</p>
</div>
</Link>
<Link
href="/turniirid"
className="px-8 md:px-12 py-8 flex flex-col gap-4 border-b-3 lg:border-r-3 group border-[#1F5673] hover:bg-[#007CAB] dark:hover:bg-[#00A3E0] transition"
className="px-8 md:px-12 py-8 flex flex-col justify-center gap-4 group border-[#1F5673] hover:bg-[#007CAB] dark:hover:bg-[#00A3E0] transition"
>
<div className="cursor-pointer flex flex-row justify-between gap-4 items-center">
<div className="flex flex-row justify-between gap-4 items-center">
<h2
className={`text-[clamp(2rem,1.8rem+1vw,3rem)] ${vipnagorgialla.className} font-bold italic break-normal uppercase dark:text-[#EEE5E5] text-[#2A2C3F] dark:group-hover:text-[#2A2C3F] group-hover:text-black`}
className={`text-[clamp(2rem,1.8rem+1vw,3rem)] ${vipnagorgialla.className} font-bold italic uppercase dark:text-[#EEE5E5] text-[#2A2C3F] dark:group-hover:text-[#2A2C3F] group-hover:text-black`}
>
{t("navigation.tournaments")}
</h2>
@@ -95,62 +58,16 @@ export default async function Home({
arrow_right_alt
</span>
</div>
<div className="flex flex-col gap-4">
<span className="material-symbols-outlined !text-[clamp(2rem,1.5rem+1.5vw,3.5rem)] text-[#007CAB] dark:text-[#00A3E0] dark:group-hover:text-[#EEE5E5] group-hover:text-[#EEE5E5]">
trophy
</span>
<p className="text-[clamp(0.875rem,0.75rem+0.5vw,1.25rem)] tracking-[-0.045rem] dark:group-hover:text-[#2A2C3F] group-hover:text-black">
{t("home.sections.tournaments.description")}
</p>
</div>
</Link>
<Link
href="/messiala"
className="px-8 md:px-12 py-8 flex flex-col gap-4 border-b-3 border-[#1F5673] group hover:bg-[#007CAB] dark:hover:bg-[#00A3E0] transition-all"
>
<div className="cursor-pointer flex flex-row justify-between gap-4 items-center">
<h2
className={`text-[clamp(2rem,1.8rem+1vw,3rem)] ${vipnagorgialla.className} font-bold italic uppercase dark:text-[#EEE5E5] text-[#2A2C3F] dark:group-hover:text-[#2A2C3F] group-hover:text-black`}
>
{t("navigation.expo")}
</h2>
<span className="material-symbols-outlined !text-[clamp(2rem,1.5rem+1.5vw,3.5rem)] !font-bold text-[#007CAB] dark:text-[#00A3E0] group-hover:translate-x-2 dark:group-hover:text-[#EEE5E5] group-hover:text-[#EEE5E5] transition">
arrow_right_alt
</span>
</div>
<div className="flex flex-col gap-4">
<span className="material-symbols-outlined !text-[clamp(2rem,1.5rem+1.5vw,3.5rem)] text-[#007CAB] dark:text-[#00A3E0] dark:group-hover:text-[#EEE5E5] group-hover:text-[#EEE5E5]">
weekend
</span>
<p className="text-[clamp(0.875rem,0.75rem+0.5vw,1.25rem)] tracking-[-0.045rem] dark:group-hover:text-[#2A2C3F] group-hover:text-black">
{t("home.sections.expo.description")}
</p>
</div>
</Link>
</div>
{/* Section preserved for next year development */}
{/* Date */}
{/* <div>*/}
{/* <Link*/}
{/* href="/piletid"*/}
{/* className={`p-8 md:p-12 flex flex-col ${vipnagorgialla.className} font-bold italic border-b-3 border-[#1F5673] hover:bg-[#007CAB] dark:hover:bg-[#00A3E0] group transition`}*/}
{/* >*/}
{/* <div className="cursor-pointer text-left flex flex-row justify-between xl:justify-start gap-8">*/}
{/* <h3 className="text-4xl md:text-5xl dark:text-[#EEE5E5] dark:group-hover:text-[#2A2C3F] text-[#2A2C3F] group-hover:text-black">*/}
{/* {t("home.sections.reserveSpot")}*/}
{/* </h3>*/}
{/* <span*/}
{/* className="material-symbols-outlined !text-[clamp(2rem,1.5rem+1.5vw,3.5rem)] !font-bold text-[#007CAB] dark:text-[#00A3E0] hidden md:block group-hover:translate-x-2 group-hover:text-[#EEE5E5] dark:group-hover:text-[#EEE5E5] transition">*/}
{/* arrow_right_alt*/}
{/* </span>*/}
{/* </div>*/}
{/* <h2 className="text-[clamp(2.5rem,2.25rem+1.25vw,3.75rem)] text-[#007CAB] dark:text-[#00A3E0] dark:group-hover:text-[#EEE5E5] group-hover:text-[#EEE5E5]">*/}
{/* {t("home.sections.dateAndLocation")}*/}
{/* </h2>*/}
{/* </Link>*/}
{/* </div>*/}
{/* Teaser carousel */}
<TeaserCarousel />
{/* Sponsors */}
<Sponsors />

View File

@@ -8,8 +8,8 @@ const workSans = Work_Sans({
});
export const metadata: Metadata = {
title: "TipiLAN 2025",
description: "TipiLAN 2025 Eesti suurim tudengite korraldatud LAN!",
title: "TipiLAN 2026",
description: "TipiLAN 2026 Eesti suurim tudengite korraldatud LAN!",
};
export default function RootLayout({

View File

@@ -1,5 +1,4 @@
import { SiDiscord, SiInstagram, SiFacebook } from "react-icons/si";
import Image from "next/image";
import { useTranslations } from "next-intl";
// Fonts
@@ -9,122 +8,82 @@ const Footer = () => {
const t = useTranslations();
return (
<div className="flex flex-col justify-center sm:justify-between px-6 py-8 md:px-12 md:py-16 gap-4 md:gap-8">
<div className="flex md:items-center gap-8 md:gap-0 justify-between flex-col md:flex-row">
<div className="flex flex-col items-start md:items-center">
<Image
src="/tipilan-white.svg"
width={250}
height={36}
alt="TipiLAN Logo"
className="h-9 dark:hidden"
/>
<Image
src="/tipilan-dark.svg"
width={250}
height={36}
alt="TipiLAN Logo"
className="h-9 not-dark:hidden"
/>
</div>
{/* Social media */}
<div className="flex flex-row">
<a
href="https://discord.gg/pPhhatZAfA"
target="_blank"
className="mx-4 ml-0 md:ml-4"
rel="noopener noreferrer"
>
<SiDiscord
title="Discord"
size={"2em"}
className="text-[#2A2C3F] dark:text-[#EEE5E5] hover:text-[#007CAB] hover:dark:text-[#00A3E0] transition"
/>
</a>
<a
href="https://instagram.com/tipilan.ee"
target="_blank"
className="mx-4"
rel="noopener noreferrer"
>
<SiInstagram
title="Instagram"
size={"2em"}
className="text-[#2A2C3F] dark:text-[#EEE5E5] hover:text-[#007CAB] hover:dark:text-[#00A3E0] transition"
/>
</a>
<a
href="https://facebook.com/tipilan.ee"
target="_blank"
className="mx-4"
rel="noopener noreferrer"
>
<SiFacebook
title="Facebook"
size={"2em"}
className="text-[#2A2C3F] dark:text-[#EEE5E5] hover:text-[#007CAB] hover:dark:text-[#00A3E0] transition"
/>
</a>
</div>
</div>
<div className="flex flex-col justify-center sm:justify-between px-6 py-6 md:px-12 md:py-8 gap-4">
<div className="flex flex-col">
<h2
className={`text-3xl sm:text-4xl ${vipnagorgialla.className} font-bold italic uppercase text-[#2A2C3F] dark:text-[#EEE5E5] mt-8 mb-4`}
className={`text-3xl sm:text-4xl ${vipnagorgialla.className} font-bold italic uppercase text-[#2A2C3F] dark:text-[#EEE5E5] mb-4`}
>
{t("footer.contact")}
</h2>
<div className="flex flex-row justify-between gap-4 items-center">
<div className="flex flex-row justify-between gap-8 items-start">
<div>
<h3 className="text-xl font-bold">{t("footer.studentUnion")}</h3>
<div className="flex flex-col gap-2 mt-2">
<div className="flex flex-row gap-2">
<span className="material-symbols-outlined !font-bold text-[#007CAB] dark:text-[#00A3E0]">
mail
</span>
<a href="mailto:tipilan@ituk.ee" className="underline">
tipilan@ituk.ee
</a>
</div>
<div className="flex flex-row gap-2">
<span className="material-symbols-outlined !font-bold text-[#007CAB] dark:text-[#00A3E0]">
phone
</span>
<a href="tel:+37256931193" className="underline">
+372 5693 1193
</a>
</div>
</div>
<h3 className="text-xl font-bold pt-4">
{t("footer.organization")}
<h3 className="text-xl font-bold">
MTÜ Lapikud
</h3>
<div>
<div className="flex flex-col gap-2 mt-2">
<p>
{t("footer.registrationCode")}:{" "}
<span className="font-semibold text-[#007CAB] dark:text-[#00A3E0]">
80391807
80167145
</span>
</p>
<p className="">ICO-210, Raja tn 4c, Tallinn, Harjumaa, 12616</p>
<p className="">Swedbank EE842200221094704780</p>
</div>
</div>
</div>
<div className="block align-middle text-center pt-16">
{t("footer.madeBy")}{" "}
<a
target="_blank"
href="https://lapikud.ee/"
className="text-[#E3983E] font-bold"
>
MTÜ Lapikud
</a>{" "}
{t("footer.withHelpFrom")}{" "}
<a
target="_blank"
href="https://ituk.ee/"
className="bg-[#7B1642] font-bold not-dark:text-white"
>
MTÜ For Tsükkel/ITÜK
</a>
<div className="flex flex-col gap-2 items-center">
<div className="flex flex-row gap-2">
<span className="material-symbols-outlined !font-bold text-[#007CAB] dark:text-[#00A3E0]">
mail
</span>
<a href="mailto:tipilaninfo@gmail.com" className="underline">
tipilaninfo@gmail.com
</a>
</div>
<div className="flex flex-row gap-2">
<span className="material-symbols-outlined !font-bold text-[#007CAB] dark:text-[#00A3E0]">
phone
</span>
<a href="tel:+37256931193" className="underline">
+372 5693 1193
</a>
</div>
</div>
{/* Social media */}
<div className="flex flex-row gap-4">
<a
href="https://discord.gg/pPhhatZAfA"
target="_blank"
rel="noopener noreferrer"
>
<SiDiscord
title="Discord"
size={"2em"}
className="text-[#2A2C3F] dark:text-[#EEE5E5] hover:text-[#007CAB] hover:dark:text-[#00A3E0] transition"
/>
</a>
<a
href="https://instagram.com/tipilan.ee"
target="_blank"
rel="noopener noreferrer"
>
<SiInstagram
title="Instagram"
size={"2em"}
className="text-[#2A2C3F] dark:text-[#EEE5E5] hover:text-[#007CAB] hover:dark:text-[#00A3E0] transition"
/>
</a>
<a
href="https://facebook.com/tipilan.ee"
target="_blank"
rel="noopener noreferrer"
>
<SiFacebook
title="Facebook"
size={"2em"}
className="text-[#2A2C3F] dark:text-[#EEE5E5] hover:text-[#007CAB] hover:dark:text-[#00A3E0] transition"
/>
</a>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,75 @@
import Image from "next/image";
import { Link } from "@/i18n/routing";
import { vipnagorgialla } from "@/components/Vipnagorgialla";
import { useTranslations } from "next-intl";
export default function HeroSection() {
const t = useTranslations("home");
return (
<section className="relative h-[569px] overflow-hidden border-b-3 border-[#1F5673]">
{/* Background image */}
<Image
src="/images/landing/main_teaser.jpg"
alt=""
fill
className="object-cover object-center"
priority
/>
{/* Dark overlay */}
<div className="absolute inset-0 bg-[#0E0F19]/75" />
{/* Content */}
<div className="relative h-full grid grid-cols-1 md:grid-cols-[3fr_2fr] items-center gap-8 px-8 md:px-12">
{/* Left: logo + info + CTA */}
<div className="flex flex-col gap-5">
<Image
src="/tipilan-dark.svg"
width={750}
height={106}
alt="TipiLAN Logo"
className="w-[max(260px,min(100%,750px))] h-auto"
/>
<div className={`${vipnagorgialla.className} font-bold italic`}>
<p className="text-[clamp(1.1rem,0.9rem+1vw,1.75rem)] text-[#00A3E0] uppercase tracking-wide">
{t("hero.date")}
</p>
<p className="text-[clamp(0.9rem,0.75rem+0.75vw,1.25rem)] text-[#EEE5E5] uppercase tracking-wide">
{t("hero.location")}
</p>
</div>
<Link
href="/piletid"
className={`self-start px-6 py-3 bg-[#007CAB] hover:bg-[#00A3E0] text-[#EEE5E5] ${vipnagorgialla.className} font-bold italic text-[clamp(1rem,0.8rem+0.8vw,1.5rem)] uppercase transition`}
>
{t("hero.buyTicket")}
</Link>
</div>
{/* Right: prize pool + award */}
<div className="flex flex-col items-start md:items-end gap-3">
<div className={`${vipnagorgialla.className} font-bold italic text-right`}>
<p className="text-[64px] leading-none tracking-normal uppercase text-[#EEE5E5]">
{t("hero.prizePool")}
</p>
<h2 className="text-[clamp(3rem,2rem+4vw,6rem)] leading-none text-[#00A3E0]">
10 000
</h2>
</div>
<div className="flex flex-row items-center md:items-center gap-0 mt-2">
<Image
src="/images/landing/student_award.webp"
width={180}
height={180}
alt="TalTech student award"
className="object-contain"
/>
<p className={`text-[32px] leading-none tracking-normal uppercase text-right align-middle text-[#EEE5E5] ${vipnagorgialla.className} font-bold italic`}>
{t("hero.awardPrefix")} <span className="text-[#00A3E0]">{t("hero.awardHighlight")}</span> {t("hero.awardSuffix")}
</p>
</div>
</div>
</div>
</section>
);
}

View File

@@ -1,8 +1,39 @@
"use client";
import { useState, useEffect, useCallback } from "react";
import { vipnagorgialla } from "@/components/Vipnagorgialla";
import { useTranslations } from "next-intl";
import Image from "next/image";
import NextLink from "next/link";
interface Sponsor {
href: string;
src: string;
alt: string;
width: number;
height: number;
className?: string;
}
const sponsors: Sponsor[] = [
{ href: "https://taltech.ee", src: "/sponsors/taltech-color.png", alt: "Taltech (Tallinna Tehnikaülikool)", width: 192, height: 192 },
{ href: "https://www.redbull.com/ee-et/", src: "/sponsors/redbull.png", alt: "Redbull", width: 80, height: 80 },
{ href: "https://www.simracing.ee/", src: "/sponsors/EVAL.png", alt: "EVAL", width: 200, height: 200 },
{ href: "https://www.facebook.com/bfglOfficial", src: "/sponsors/BFGL.png", alt: "BFGL", width: 192, height: 192 },
{ href: "https://www.tomorrow.ee/", src: "/sponsors/nt.png", alt: "Network Tomorrow", width: 300, height: 200 },
{ href: "https://k-space.ee/", src: "/sponsors/k-space_ee-white.png", alt: "K-Space", width: 200, height: 200, className: "not-dark:invert" },
{ href: "https://globalproductions.ee/", src: "/sponsors/Global-productions.png", alt: "Global Productions", width: 200, height: 200 },
{ href: "https://www.linkedin.com/company/gamedev-guild/", src: "/sponsors/estonian_gamedev_guild.png", alt: "Estonian Gamedev Guild", width: 200, height: 200, className: "not-dark:invert" },
{ href: "https://alzgamer.ee/", src: "/sponsors/alzgamer.png", alt: "AlzGamer", width: 200, height: 200 },
];
// Split sponsors into slides (6 per slide)
const SPONSORS_PER_SLIDE = 6;
const slides: Sponsor[][] = [];
for (let i = 0; i < sponsors.length; i += SPONSORS_PER_SLIDE) {
slides.push(sponsors.slice(i, i + SPONSORS_PER_SLIDE));
}
interface SponsorsProps {
showTitle?: boolean;
className?: string;
@@ -13,191 +44,65 @@ export default function Sponsors({
className = "",
}: SponsorsProps) {
const t = useTranslations();
const [current, setCurrent] = useState(0);
const next = useCallback(() => setCurrent((c) => (c + 1) % slides.length), []);
useEffect(() => {
const id = setInterval(next, 5000);
return () => clearInterval(id);
}, [next]);
return (
<div
className={`p-12 flex flex-col ${vipnagorgialla.className} font-bold italic border-b-3 border-[#1F5673] ${className}`}
className={`flex flex-col max-w-[1920px] h-[414px] mx-auto ${vipnagorgialla.className} font-bold italic border-b-3 border-[#1F5673] ${className}`}
>
<div className="text-left flex flex-col justify-between xl:justify-start">
{showTitle && (
<h3 className="text-4xl md:text-5xl dark:text-[#EEE5E5] text-[#2A2C3F] group-hover:text-black pb-8">
{t("home.sections.poweredBy")}
</h3>
)}
<div className="flex flex-col sm:flex-row flex-wrap gap-8 md:gap-18 items-center justify-center xl:justify-start">
<NextLink href="https://taltech.ee" target="_blank">
<Image
src="/sponsors/taltech-color.png"
alt="Taltech (Tallinna Tehnikaülikool)"
width={192}
height={192}
className="object-contain"
/>
</NextLink>
<NextLink href="https://www.redbull.com/ee-et/" target="_blank">
<Image
src="/sponsors/redbull.png"
alt="Redbull"
width={80}
height={80}
className="object-contain"
/>
</NextLink>
<NextLink href="https://www.alecoq.ee" target="_blank">
<Image
src="/sponsors/alecoq.svg"
alt="Alecoq"
width={200}
height={200}
className="object-contain"
/>
</NextLink>
<NextLink href="https://www.simracing.ee/" target="_blank">
<Image
src="/sponsors/EVAL.png"
alt="EVAL"
width={200}
height={200}
className="object-contain"
/>
</NextLink>
<NextLink href="https://balsnack.ee" target="_blank">
<Image
src="/sponsors/balsnack.svg"
alt="Balsnack"
width={200}
height={200}
className="object-contain"
/>
</NextLink>
<NextLink
href="https://www.rara.ee/sundmused/interaktiivne-videomangude-muuseum-lvlup/"
target="_blank"
>
<Image
src="/sponsors/lvlup_logo_export.svg"
alt="LVLup!"
width={192}
height={192}
className="object-contain"
/>
</NextLink>
<NextLink
href="https://www.facebook.com/bfglOfficial"
target="_blank"
>
<Image
src="/sponsors/BFGL.png"
alt="BFGL"
width={192}
height={192}
className="object-contain"
/>
</NextLink>
<NextLink href="https://www.tallinn.ee/et/haridus" target="_blank">
<Image
src="/sponsors/Tallinna_Haridusamet_logo_RGB.svg"
alt="Tallinna Haridusamet"
width={292}
height={292}
className="object-contain"
/>
</NextLink>
<NextLink href="https://www.militaarseiklus.ee/" target="_blank">
<Image
src="/sponsors/militaarseiklus.png"
alt="Militaarseiklus"
width={200}
height={200}
className="object-contain"
/>
</NextLink>
<NextLink
href="https://www.linkedin.com/company/gamedev-guild/"
target="_blank"
>
<Image
src="/sponsors/estonian_gamedev_guild.png"
alt="Estonian Gamedev Guild"
width={200}
height={200}
className="object-contain not-dark:invert"
/>
</NextLink>
<NextLink href="https://thotell.ee/" target="_blank">
<Image
src="/sponsors/thotell.png"
alt="Tahentorni Hotell (Tähentorni Hotel)"
width={200}
height={200}
className="object-contain"
/>
</NextLink>
<NextLink href="https://www.dominos.ee/" target="_blank">
<Image
src="/sponsors/dominos.png"
alt="Domino's Pizza"
width={250}
height={250}
className="object-contain"
/>
</NextLink>
<NextLink href="https://www.tomorrow.ee/" target="_blank">
<Image
src="/sponsors/nt.png"
alt="Network Tomorrow"
width={300}
height={200}
className="object-contain"
/>
</NextLink>
<NextLink href="https://driftikeskus.ee/" target="_blank">
<Image
src="/sponsors/driftikeskus.png"
alt="Driftikeskus"
width={300}
height={200}
className="object-contain"
/>
</NextLink>
<NextLink href="https://ingame.ee/" target="_blank">
<Image
src="/sponsors/ingame.png"
alt="Ingame"
width={200}
height={200}
className="object-contain"
/>
</NextLink>
<NextLink href="https://alzgamer.ee/" target="_blank">
<Image
src="/sponsors/alzgamer.png"
alt="AlzGamer"
width={200}
height={200}
className="object-contain"
/>
</NextLink>
<NextLink href="https://k-space.ee/" target="_blank">
<Image
src="/sponsors/k-space_ee-white.png"
alt="K-Space"
width={200}
height={200}
className="object-contain not-dark:invert"
/>
</NextLink>
<NextLink href="https://globalproductions.ee/" target="_blank">
<Image
src="/sponsors/Global-productions.png"
alt="Global Productions"
width={200}
height={200}
className="object-contain"
/>
</NextLink>
{showTitle && (
<h3 className="text-4xl md:text-5xl dark:text-[#EEE5E5] text-[#2A2C3F] px-12 pt-8 pb-4">
{t("home.sections.poweredBy")}
</h3>
)}
{/* Carousel container */}
<div className="relative flex-1 overflow-hidden">
<div
className="flex h-full transition-transform duration-500 ease-in-out"
style={{ transform: `translateX(-${current * 100}%)` }}
>
{slides.map((slideSponsors, slideIndex) => (
<div
key={slideIndex}
className="flex-none w-full h-full flex items-center justify-center gap-8 md:gap-12 px-12"
>
{slideSponsors.map((sponsor, i) => (
<NextLink key={i} href={sponsor.href} target="_blank">
<Image
src={sponsor.src}
alt={sponsor.alt}
width={sponsor.width}
height={sponsor.height}
className={`object-contain max-h-[180px] ${sponsor.className || ""}`}
/>
</NextLink>
))}
</div>
))}
</div>
</div>
{/* Navigation dots */}
<div className="flex justify-center gap-3 py-4">
{slides.map((_, i) => (
<button
key={i}
onClick={() => setCurrent(i)}
className={`w-3 h-3 rounded-full transition ${
i === current ? "bg-[#007CAB]" : "bg-[#1F5673] hover:bg-[#007CAB]/60"
}`}
aria-label={`Slide ${i + 1}`}
/>
))}
</div>
</div>
);
}

View File

@@ -0,0 +1,143 @@
"use client";
import { useState, useEffect, useCallback } from "react";
import Image from "next/image";
import { Link } from "@/i18n/routing";
import { vipnagorgialla } from "@/components/Vipnagorgialla";
import { useTranslations } from "next-intl";
type Slide = {
key: "compete" | "play" | "explore";
image: string;
imageAlt: string;
hero: string;
href: "/turniirid" | "/piletid" | "/messiala";
flip?: boolean;
fullBrightness?: boolean;
};
// Helper to highlight "LAN" in "TIPILAN" with blue color
function highlightLAN(text: string) {
const parts = text.split(/(TIPILAN\w*)/gi);
return parts.map((part, i) => {
const upper = part.toUpperCase();
if (upper.startsWith("TIPILAN")) {
const suffix = part.slice(7); // Everything after "TIPILAN"
return (
<span key={i}>
TIPI<span className="text-[#00A3E0]">LAN</span>{suffix.toUpperCase()}
</span>
);
}
return part;
});
}
const slides: Slide[] = [
{ key: "compete", image: "/images/landing/compete_teaser.jpg", imageAlt: "Võistle", hero: "/images/landing/compete_hero.png", href: "/turniirid" },
{ key: "play", image: "/images/landing/play_teaser.png", imageAlt: "Mängi", hero: "/images/landing/play_hero.png", href: "/piletid", flip: true, fullBrightness: true },
{ key: "explore", image: "/images/landing/explore_teaser.png", imageAlt: "Avasta", hero: "/images/landing/explore_hero.png", href: "/messiala", fullBrightness: true },
];
export default function TeaserCarousel() {
const t = useTranslations("home.teaser");
const [current, setCurrent] = useState(0);
const next = useCallback(() => setCurrent((c) => (c + 1) % slides.length), []);
const prev = () => setCurrent((c) => (c - 1 + slides.length) % slides.length);
useEffect(() => {
const id = setInterval(next, 5000);
return () => clearInterval(id);
}, [next]);
return (
<div className="border-b-3 border-[#1F5673]">
{/* Sliding track */}
<div className="relative h-[729px] overflow-hidden">
<div
className="flex h-full transition-transform duration-500 ease-in-out"
style={{ transform: `translateX(-${current * 100}%)` }}
>
{slides.map((slide) => {
const title = t(`${slide.key}.title`);
const description = t(`${slide.key}.description`);
return (
<div key={slide.key} className="relative flex-none w-full h-full">
{/* Background image */}
<Image
src={slide.image}
alt={slide.imageAlt}
fill
className="object-cover object-center"
/>
{/* Overlay */}
<div className={`absolute inset-0 ${slide.fullBrightness ? "" : "bg-gradient-to-r from-[#0E0F19]/90 via-[#0E0F19]/60 to-[#0E0F19]/20"}`} />
{/* Content */}
<div className={`relative grid grid-cols-1 md:grid-cols-2 h-full ${slide.flip ? "md:[direction:rtl]" : ""}`}>
<div className={`flex flex-col justify-between px-8 py-8 md:px-12 md:py-10 ${slide.flip ? "md:[direction:ltr]" : ""}`}>
{/* Heading at top */}
<h2 className={`${vipnagorgialla.className} font-bold italic text-[64px] leading-none tracking-normal uppercase text-[#EEE5E5]`}>
{highlightLAN(t("heading"))}
</h2>
{/* Title + description at bottom */}
<div className="flex flex-col gap-3 pb-16">
<Link href={slide.href}>
<h3 className={`${vipnagorgialla.className} font-bold italic text-[clamp(2.5rem,2rem+2.5vw,5rem)] leading-none text-[#EEE5E5] hover:text-[#00A3E0] transition`}>
{title}
</h3>
</Link>
<p className="text-[clamp(0.875rem,0.75rem+0.5vw,1.1rem)] text-[#EEE5E5] max-w-prose">
{description}
</p>
</div>
</div>
{/* Hero image */}
<div className={`hidden md:block relative ${slide.flip ? "md:[direction:ltr]" : ""}`}>
<Image
src={slide.hero}
alt={slide.imageAlt}
fill
className="object-contain object-bottom"
/>
</div>
</div>
</div>
);
})}
</div>
{/* Arrow buttons */}
<button
onClick={prev}
className="absolute left-4 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center bg-[#0E0F19]/50 hover:bg-[#007CAB] text-[#EEE5E5] transition"
aria-label="Previous slide"
>
<span className="material-symbols-outlined">chevron_left</span>
</button>
<button
onClick={next}
className="absolute right-4 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center bg-[#0E0F19]/50 hover:bg-[#007CAB] text-[#EEE5E5] transition"
aria-label="Next slide"
>
<span className="material-symbols-outlined">chevron_right</span>
</button>
</div>
{/* Navigation dots */}
<div className="flex justify-center gap-3 py-5">
{slides.map((_, i) => (
<button
key={i}
onClick={() => setCurrent(i)}
className={`w-3 h-3 rounded-full transition ${
i === current ? "bg-[#007CAB]" : "bg-[#1F5673] hover:bg-[#007CAB]/60"
}`}
aria-label={`Slide ${i + 1}`}
/>
))}
</div>
</div>
);
}

View File

@@ -35,10 +35,37 @@
}
},
"home": {
"title": "TipiLAN 2025",
"title": "TipiLAN 2026",
"subtitle": "Estonia's largest student-organized LAN event!",
"welcome": "Welcome to TipiLAN 2025!",
"welcome": "Welcome to TipiLAN 2026!",
"description": "Join us at Estonia's largest student-organized LAN event. Games, competitions and much more await you!",
"hero": {
"date": "1113 OCTOBER 2026",
"location": "TALTECH, EHITAJATE TEE 5",
"buyTicket": "BUY TICKETS",
"prizePool": "PRIZE POOL",
"awardPrefix": "TALTECH",
"awardHighlight": "STUDENT ACT OF THE YEAR",
"awardSuffix": "2025"
},
"teaser": {
"heading": "COME TO TIPILAN AND...",
"compete": {
"title": "COMPETE",
"description": "Prove yourself in TipiLAN's CS2 and LoL tournaments: thousands in prize money, players from across Europe, and HLTV-ranked competition that could put you on the map.",
"link": "/turniirid"
},
"play": {
"title": "PLAY",
"description": "Enjoy the TipiLAN atmosphere — bring your computer, relax, play with friends and experience one of Estonia's largest gaming events.",
"link": "/piletid"
},
"explore": {
"title": "EXPLORE",
"description": "Explore the TipiLAN expo area where companies, mini-competitions and lots more exciting things await you.",
"link": "/messiala"
}
},
"sections": {
"schedule": {
"description": "TipiLAN is packed with exciting tournaments, mini-competitions and much more."
@@ -51,8 +78,7 @@
},
"reserveSpot": "Reserve your spot today!",
"poweredBy": "TipiLAN is powered by...",
"dateAndLocation": "24th-26th Oct. @ TalTech main building",
"farewellMessage": "Thank you for partici\u00ADpating in TipiLAN 2025! We hope to see you again next time!"
"dateAndLocation": "11th13th Oct. @ TalTech"
}
},
"tickets": {

View File

@@ -35,10 +35,37 @@
}
},
"home": {
"title": "TipiLAN 2025",
"title": "TipiLAN 2026",
"subtitle": "Eesti suurim tudengite korraldatud LAN!",
"welcome": "Tere tulemast TipiLAN 2025 sündmusele!",
"welcome": "Tere tulemast TipiLAN 2026 sündmusele!",
"description": "Liitu meiega Eesti suurimal tudengite korraldatud LAN-üritusel. Mängud, võistlused ja palju muud ootavad sind!",
"hero": {
"date": "11.13. OKTOOBER 2026",
"location": "TALTECH, EHITAJATE TEE 5",
"buyTicket": "OSTA PILET",
"prizePool": "AUHINNAFOND",
"awardPrefix": "TALTECHI",
"awardHighlight": "AASTA TUDENGITEGU",
"awardSuffix": "2025"
},
"teaser": {
"heading": "TULE TIPILANILE JA...",
"compete": {
"title": "VÕISTLE",
"description": "Tõesta end TipiLANi CS2 ja LoL featurniiridel: tuhanded eurod auhinnarahas, mängijad üle kogu Euroopa ja HLTV-reitinguga võistlus, mis viib sind maailmakaardile.",
"link": "/turniirid"
},
"play": {
"title": "MÄNGI",
"description": "Naudi TipiLANi atmosfääri too kaasa arvuti, istutle mugavalt, mängi sõpradega ja koge ühte Eesti suurimat mänguüritust.",
"link": "/piletid"
},
"explore": {
"title": "AVASTA",
"description": "Avasta TipiLANi messialat, kus ootavad sind erinevad ettevõtted, mini-võistlused ja palju muud põnevat.",
"link": "/messiala"
}
},
"sections": {
"schedule": {
"description": "TipiLAN on pungil põnevatest turniiridest, mini-võistlustest ja paljust muust."
@@ -51,8 +78,7 @@
},
"reserveSpot": "Broneeri oma koht juba täna!",
"poweredBy": "TipiLANi tõmbab käima...",
"dateAndLocation": "24.-26. okt. TalTechi peahoones",
"farewellMessage": "Aitäh, et olite osa TipiLAN 2025-st! Ootame teid tagasi järgmisele!"
"dateAndLocation": "11.13. okt. TalTechis"
}
},
"tickets": {

View File

@@ -1,7 +1,11 @@
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
@@ -11,7 +15,7 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
@@ -19,9 +23,19 @@
}
],
"paths": {
"@/*": ["./src/*"]
"@/*": [
"./src/*"
]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}