Home, card, mentors page update

This commit is contained in:
2026-02-23 23:06:41 +02:00
parent c1cd4aeb8f
commit 4a452e9793
5 changed files with 235 additions and 168 deletions

View File

@@ -1,6 +1,6 @@
<script>
export let href = "";
export let variant = "default"; // 'default' | 'animated' | 'animated-neutral' | 'glass'
export let variant = "default"; // 'default' | 'animated' | 'animated-neutral' | 'glass' | 'blur'
export let className = "";
const variantClasses = {
@@ -8,6 +8,7 @@
animated: "card-animated",
"animated-neutral": "card-animated-neutral",
glass: "card-glass",
blur: "card-blur",
};
</script>
@@ -80,6 +81,35 @@
transform: none;
}
.card-blur {
background: rgba(255, 255, 255, 0.68);
backdrop-filter: blur(18px) saturate(160%);
-webkit-backdrop-filter: blur(18px) saturate(160%);
border: 1px solid rgba(255, 255, 255, 0.55);
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.06);
isolation: isolate;
}
.card-blur::before {
content: "";
position: absolute;
inset: -12px;
border-radius: calc(var(--radius-lg) + 12px);
background: radial-gradient(
120% 120% at 50% 50%,
rgba(245, 245, 245, 0.95) 45%,
rgba(245, 245, 245, 0.55) 65%,
rgba(245, 245, 245, 0) 82%
);
filter: blur(10px);
pointer-events: none;
z-index: -1;
}
.card-blur:hover {
background: rgba(255, 255, 255, 0.78);
}
@media (max-width: 768px) {
.card {
padding: var(--space-4);

View File

@@ -195,11 +195,11 @@
<!-- Full Screen Mobile Menu -->
{#if mobileMenuOpen}
<div
class="fixed inset-0 z-100 bg-(--off-black) md:hidden overflow-hidden"
class="fixed inset-0 z-100 bg-(--off-black) md:hidden overflow-y-auto"
class:menu-opening={!isClosing}
class:menu-closing={isClosing}
>
<Stack className="h-full">
<Stack className="min-h-full">
<div class="absolute top-8 right-0 px-(--site-padding)">
<Button
onClick={closeMobileMenu}
@@ -212,7 +212,7 @@
</div>
<!-- Menu Content -->
<Stack gap="var(--space-5)" className="flex-1 px-8 pb-8 text-white text-xl justify-center">
<Stack gap="var(--space-5)" className="flex-1 px-8 pt-24 pb-12 text-white text-xl">
<!-- About Section -->
<Stack gap="var(--space-3)">
<h3 class="text-2xl font-bold" style="color: var(--orange)">{$text.about}</h3>
@@ -320,4 +320,4 @@
</Stack>
</Stack>
</div>
{/if}
{/if}

View File

@@ -39,7 +39,7 @@
<Section>
<Grid gap="var(--space-5)">
<Card variant="animated-neutral" href="/tudengile">
<Card variant="blur" href="/tudengile">
<div class="feature-icon" style="color: var(--orange)">
<Users size={32} strokeWidth={1.5} />
</div>
@@ -52,7 +52,7 @@
</div>
</Card>
<Card variant="animated-neutral" href="/helpdesk">
<Card variant="blur" href="/helpdesk">
<div class="feature-icon" style="color: var(--orange)">
<Wrench size={32} strokeWidth={1.5} />
</div>
@@ -65,7 +65,7 @@
</div>
</Card>
<Card variant="animated-neutral" href="/ourwork">
<Card variant="blur" href="/ourwork">
<div class="feature-icon" style="color: var(--orange)">
<HeartHandshake size={32} strokeWidth={1.5} />
</div>
@@ -83,11 +83,11 @@
<!-- What We Do Section -->
<Section>
<Grid gap="var(--space-4)">
<Card variant="glass">
<Card variant="blur">
<h2 class="pb-4 text-4xl font-bold">Mida me loome</h2>
<p>Meie põhieesmärgiks on Tallinna Tehnikaülikooli IT tudengitele erialase lisandväärtuse loomine. Kaasame tudengeid praktilistesse lahendustesse, kus saab ideid reaalselt ellu viia ja oma oskusi päriselt kasutada. Meie projektidest kasvavad välja huvitavad ja tarvilikud lõputööd, millel on selge praktiline väärtus.</p>
</Card>
<Card variant="glass">
<Card variant="blur">
<h2 class="pb-4 text-4xl font-bold">Keda ja kuidas kaasame</h2>
<p>Pakume nutikatele ja motiveeritud tudengitele võimalust saada meie juures esimene töökogemus ning arendada end meeskonnas töötades. Lapikud ei ole ainult IT-tudengite organisatsioon, kaasame projektidesse ka majandusteaduskonna tudengeid, et tehniliste lahenduste kõrval oleks esindatud ka äriline vaade.</p>
</Card>

View File

@@ -1,176 +1,213 @@
<script>
import {
Section,
Grid,
Card,
Center,
} from "$components";
import { onMount } from "svelte";
import yaml from 'js-yaml';
import { currentLang, getLangText } from "$lib";
import Mail from "lucide-svelte/icons/mail";
import Phone from "lucide-svelte/icons/phone";
import MessageCircle from "lucide-svelte/icons/message-circle";
import User from "lucide-svelte/icons/user";
import { Section, Card, Center } from "$components";
import { onMount } from "svelte";
import yaml from "js-yaml";
import { currentLang, getLangText } from "$lib";
let mentors = [];
onMount(async () => {
const response = await fetch('/_data/mentors.yml');
const yamlText = await response.text();
mentors = yaml.load(yamlText);
});
import Mail from "lucide-svelte/icons/mail";
import Phone from "lucide-svelte/icons/phone";
import MessageCircle from "lucide-svelte/icons/message-circle";
import User from "lucide-svelte/icons/user";
function getContactIcon(contactType) {
const type = contactType.toLowerCase();
if (type.includes('email') || type.includes('e-post')) return Mail;
if (type.includes('phone') || type.includes('telefon')) return Phone;
if (type.includes('messenger') || type.includes('discord') || type.includes('facebook')) return MessageCircle;
return User;
}
let mentors = [];
function getContactLink(method) {
const type = method.name.toLowerCase();
const value = method.value;
if (type.includes('email')) return `mailto:${value}`;
if (type.includes('phone') || type.includes('telefon')) return `tel:${value}`;
if (type.includes('messenger') || type.includes('facebook')) {
return value.startsWith('http') ? value : `https://m.me/${value}`;
onMount(async () => {
const response = await fetch("/_data/mentors.yml");
const yamlText = await response.text();
mentors = yaml.load(yamlText);
});
function getContactIcon(contactType) {
const type = contactType.toLowerCase();
if (type.includes("email") || type.includes("e-post")) return Mail;
if (type.includes("phone") || type.includes("telefon")) return Phone;
if (
type.includes("messenger") ||
type.includes("discord") ||
type.includes("facebook")
)
return MessageCircle;
return User;
}
function getContactLink(method) {
const type = method.name.toLowerCase();
const value = method.value;
if (type.includes("email")) return `mailto:${value}`;
if (type.includes("phone") || type.includes("telefon"))
return `tel:${value}`;
if (type.includes("messenger") || type.includes("facebook")) {
return value.startsWith("http") ? value : `https://m.me/${value}`;
}
if (type.includes("discord")) return "#";
return value.startsWith("http") ? value : "#";
}
if (type.includes('discord')) return '#';
return value.startsWith('http') ? value : '#';
}
</script>
<!-- Hero Section -->
<Section background="orange">
<Center>
<div class="text-center max-w-4xl">
<h1 class="text-5xl font-bold mb-6">Meie Mentorid</h1>
<p class="text-2xl leading-relaxed">
Kogenud tudengid, kes aitavad sind areneda ja jagavad oma teadmisi
</p>
</div>
</Center>
<Center>
<div class="text-center max-w-4xl">
<h1 class="text-5xl font-bold mb-6">Meie Mentorid</h1>
<p class="text-2xl leading-relaxed">
Kogenud tudengid, kes aitavad sind areneda ja jagavad oma
teadmisi
</p>
</div>
</Center>
</Section>
<!-- Mentors Grid -->
<Section>
<div class="text-center mb-12">
<h2 class="text-4xl font-bold mb-4">Tutvuge meie mentorite meeskonnaga</h2>
<p class="text-xl text-gray-600">Igaüks neist on spetsialist omas valdkonnas ja valmis sind aitama</p>
</div>
<Grid columns={2} gap="var(--space-6)">
{#each mentors as mentor}
<Card variant="glass" class="overflow-hidden">
<div class="flex flex-col md:flex-row gap-6">
<!-- Mentor Photo -->
{#if mentor.photo}
<div class="shrink-0">
<img
src={`/assets/mentors-images/optimised/${mentor.photo}`}
alt={mentor.name}
class="w-full md:w-48 h-48 object-cover rounded-lg"
on:error={(e) => {
e.target.src = '/assets/mentors-images/original/' + mentor.photo;
}}
/>
<div class="text-center mb-12">
<h2 class="text-4xl font-bold mb-4">
Tutvuge meie mentorite meeskonnaga
</h2>
<p class="text-xl text-gray-600">
Igaüks neist on spetsialist omas valdkonnas ja valmis sind aitama
</p>
</div>
<div class="flex flex-col gap-8">
{#each mentors as mentor}
<div>
<div class="flex flex-col md:flex-row gap-6">
<!-- Mentor Photo -->
{#if mentor.photo}
<div class="shrink-0">
<img
src={`/assets/mentors-images/optimised/${mentor.photo}`}
alt={mentor.name}
class="w-full md:w-48 h-48 object-cover"
on:error={(e) => {
e.target.src =
"/assets/mentors-images/original/" +
mentor.photo;
}}
/>
</div>
{/if}
<!-- Mentor Info -->
<div class="flex-1">
<h3 class="text-2xl font-bold mb-2">{mentor.name}</h3>
{#if mentor.age}
<p class="text-gray-600 mb-2">
Vanus: {mentor.age}
</p>
{/if}
{#if mentor.speciality}
<p
class="text-lg font-semibold mb-2"
style="color: var(--orange)"
>
{getLangText(
mentor,
"speciality",
$currentLang,
)}
</p>
{/if}
{#if mentor.teams && mentor.teams.length > 0}
<div class="mb-3">
<span class="font-semibold">Meeskonnad: </span>
<span class="text-gray-700"
>{mentor.teams.join(", ")}</span
>
</div>
{/if}
{#if mentor.term}
<p class="text-gray-600 mb-3">
Ametiperiood: {mentor.term}
{mentor.term === 1 ? "aasta" : "aastat"}
</p>
{/if}
{#if mentor.description}
<p
class="text-sm font-semibold mb-2"
style="color: var(--orange)"
>
Otsin: {getLangText(
mentor,
"description",
$currentLang,
)}
</p>
{/if}
{#if mentor.activities}
<p class="text-gray-700 text-sm mb-4">
{getLangText(
mentor,
"activities",
$currentLang,
)}
</p>
{/if}
<!-- Contact Methods -->
{#if mentor.contactMethods && mentor.contactMethods.length > 0}
<div class="flex flex-wrap gap-2 mt-4">
{#each mentor.contactMethods as method}
{@const IconComponent = getContactIcon(
method.name,
)}
<a
href={getContactLink(method)}
class="inline-flex items-center gap-2 px-3 py-2 bg-orange-100 hover:bg-orange-200 rounded-lg transition-colors text-sm"
title={method.name}
target={method.value.startsWith("http")
? "_blank"
: "_self"}
rel={method.value.startsWith("http")
? "noopener noreferrer"
: ""}
>
<svelte:component
this={IconComponent}
size={16}
/>
<span class="capitalize"
>{method.name}</span
>
</a>
{/each}
</div>
{/if}
</div>
</div>
</div>
{/if}
<!-- Mentor Info -->
<div class="flex-1">
<h3 class="text-2xl font-bold mb-2">{mentor.name}</h3>
{#if mentor.age}
<p class="text-gray-600 mb-2">Vanus: {mentor.age}</p>
{/if}
{#if mentor.speciality}
<p class="text-lg font-semibold mb-2" style="color: var(--orange)">
{getLangText(mentor, 'speciality', $currentLang)}
</p>
{/if}
{#if mentor.teams && mentor.teams.length > 0}
<div class="mb-3">
<span class="font-semibold">Meeskonnad: </span>
<span class="text-gray-700">{mentor.teams.join(', ')}</span>
</div>
{/if}
{#if mentor.term}
<p class="text-gray-600 mb-3">Ametiperiood: {mentor.term} {mentor.term === 1 ? 'aasta' : 'aastat'}</p>
{/if}
{#if mentor.description}
<p class="text-sm font-semibold mb-2" style="color: var(--orange)">
Otsin: {getLangText(mentor, 'description', $currentLang)}
</p>
{/if}
{#if mentor.activities}
<p class="text-gray-700 text-sm mb-4 line-clamp-3">
{getLangText(mentor, 'activities', $currentLang)}
</p>
{/if}
<!-- Contact Methods -->
{#if mentor.contactMethods && mentor.contactMethods.length > 0}
<div class="flex flex-wrap gap-2 mt-4">
{#each mentor.contactMethods as method}
{@const IconComponent = getContactIcon(method.name)}
<a
href={getContactLink(method)}
class="inline-flex items-center gap-2 px-3 py-2 bg-orange-100 hover:bg-orange-200 rounded-lg transition-colors text-sm"
title={method.name}
target={method.value.startsWith('http') ? '_blank' : '_self'}
rel={method.value.startsWith('http') ? 'noopener noreferrer' : ''}
>
<svelte:component this={IconComponent} size={16} />
<span class="capitalize">{method.name}</span>
</a>
{/each}
</div>
{/if}
</div>
</div>
</Card>
{/each}
</Grid>
{/each}
</div>
</Section>
<!-- Become a Mentor Section -->
<Section background="neutral">
<Center>
<Card variant="glass" class="max-w-3xl">
<h2 class="text-4xl font-bold mb-6 text-center">Taha saada mentoriks?</h2>
<p class="text-lg text-center mb-6">
Kui oled kogenud tudeng ja soovid jagada oma teadmisi ning aidata uusi liikmeid,
siis võta meiega ühendust!
</p>
<div class="text-center">
<a
href="mailto:lapikud@lapikud.ee"
class="inline-block px-8 py-3 bg-orange-500 hover:bg-orange-600 text-white font-semibold rounded-lg transition-colors"
>
Võta ühendust
</a>
</div>
</Card>
</Center>
<Center>
<Card variant="glass" class="max-w-3xl">
<h2 class="text-4xl font-bold mb-6 text-center">
Taha saada mentoriks?
</h2>
<p class="text-lg text-center mb-6">
Kui oled kogenud tudeng ja soovid jagada oma teadmisi ning
aidata uusi liikmeid, siis võta meiega ühendust!
</p>
<div class="text-center">
<a
href="mailto:lapikud@lapikud.ee"
class="inline-block px-8 py-3 bg-orange-500 hover:bg-orange-600 text-white font-semibold rounded-lg transition-colors"
>
Võta ühendust
</a>
</div>
</Card>
</Center>
</Section>
<style>
.line-clamp-3 {
display: -webkit-box;
-webkit-line-clamp: 3;
line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
</style>

View File

@@ -171,7 +171,7 @@
{#if members.senior && members.senior.length > 0}
<div class="mb-12">
<h3 class="text-3xl font-bold mb-6 text-center">Senior liikmed</h3>
<h3 class="text-3xl font-bold mb-6 text-center">Vanemliikmed</h3>
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
{#each members.senior as member}
<div class="bg-white rounded-lg p-4 shadow-sm hover:shadow-md transition-shadow">
@@ -184,7 +184,7 @@
{#if members.junior && members.junior.length > 0}
<div>
<h3 class="text-3xl font-bold mb-6 text-center">Junior liikmed</h3>
<h3 class="text-3xl font-bold mb-6 text-center">Noorliikmed</h3>
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
{#each members.junior as member}
<div class="bg-white rounded-lg p-4 shadow-sm hover:shadow-md transition-shadow">