mirror of
https://github.com/Lapikud/lapikud.github.io.git
synced 2026-08-08 22:59:14 +00:00
lang changes, new pages, data changes
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<script>
|
||||
export let onClick = () => {};
|
||||
export let buttonHoverStyle = "";
|
||||
export let style = "";
|
||||
|
||||
let isHovered = false;
|
||||
</script>
|
||||
@@ -10,7 +11,7 @@
|
||||
on:mouseenter={() => (isHovered = true)}
|
||||
on:mouseleave={() => (isHovered = false)}
|
||||
class={`btn border-[1.5px] px-5 py-2.5 font-medium cursor-pointer flex items-center gap-2 whitespace-nowrap ${$$restProps.class}`}
|
||||
style={isHovered && buttonHoverStyle ? buttonHoverStyle : null}
|
||||
style={isHovered && buttonHoverStyle ? buttonHoverStyle : style}
|
||||
>
|
||||
<slot />
|
||||
</button>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
Section,
|
||||
Stack,
|
||||
} from "$components";
|
||||
import { navigate, getPath, currentLang, text, switchLang } from "$lib";
|
||||
import { navigate, getPath, currentLang, text, switchLanguageRoute } from "$lib";
|
||||
import { onDestroy } from "svelte";
|
||||
|
||||
// Icon imports (Lucide)
|
||||
@@ -58,6 +58,11 @@
|
||||
navigate(path, options);
|
||||
closeMobileMenu();
|
||||
}
|
||||
|
||||
function handleLanguageSwitch(lang) {
|
||||
switchLanguageRoute(lang);
|
||||
closeMobileMenu();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@@ -93,58 +98,69 @@
|
||||
<!-- Desktop Navigation -->
|
||||
<nav class="z-10 hidden md:flex gap-4 justify-end text-xl">
|
||||
<Dropdown
|
||||
name={$text.nav.about}
|
||||
name={$text.about}
|
||||
buttonClass="rounded-[5px]"
|
||||
buttonHoverStyle="background-color:var(--orange); color:var(--black)"
|
||||
panelClassName="bg-[var(--off-black)]"
|
||||
>
|
||||
<Button class="rounded-[5px] bg-transparent" buttonHoverStyle="color:var(--orange)" onClick={() => navigate("/mis-teeme")}
|
||||
>{$text.nav.aboutPages.info}</Button
|
||||
<Button class="rounded-[5px] bg-transparent" buttonHoverStyle="color:var(--orange)" onClick={() => navigate("/lapikutest")}
|
||||
>{$text.aboutPages.info}</Button
|
||||
>
|
||||
<Button class="rounded-[5px] bg-transparent" buttonHoverStyle="color:var(--orange)" onClick={() => navigate("/liitu-meiega")}
|
||||
><Bot />{$text.nav.aboutPages.join}</Button
|
||||
<Button class="rounded-[5px] bg-transparent" buttonHoverStyle="color:var(--orange)" onClick={() => navigate("/tudengile")}
|
||||
><Bot />{$text.aboutPages.join}</Button
|
||||
>
|
||||
<Button class="rounded-[5px] bg-transparent" buttonHoverStyle="color:var(--orange)" onClick={() => navigate("/mentorid")}
|
||||
><HandHeart />{$text.nav.aboutPages.mentors}</Button
|
||||
><HandHeart />{$text.aboutPages.mentors}</Button
|
||||
>
|
||||
<Button class="rounded-[5px] bg-transparent" buttonHoverStyle="color:var(--orange)" onClick={() => navigate("/juhatus")}
|
||||
><Lectern />{$text.nav.aboutPages.board}</Button
|
||||
><Lectern />{$text.aboutPages.board}</Button
|
||||
>
|
||||
</Dropdown>
|
||||
<Dropdown
|
||||
name={$text.nav.events}
|
||||
name={$text.events}
|
||||
buttonClass="rounded-[5px]"
|
||||
buttonHoverStyle="background-color:var(--orange); color:var(--black)"
|
||||
panelClassName="bg-[var(--off-black)]"
|
||||
>
|
||||
<Button class="rounded-[5px] bg-transparent" buttonHoverStyle="color:var(--orange)" onClick={() => navigate("/kalender")}
|
||||
><CalendarClock />{$text.nav.eventsPages.calendar}</Button
|
||||
><CalendarClock />{$text.eventsPages.calendar}</Button
|
||||
>
|
||||
<Button class="rounded-[5px] bg-transparent" buttonHoverStyle="color:var(--orange)" onClick={() => navigate("/koolitused")}
|
||||
><Presentation />{$text.nav.eventsPages.workshops}</Button
|
||||
><Presentation />{$text.eventsPages.workshops}</Button
|
||||
>
|
||||
<Button class="rounded-[5px] bg-transparent" buttonHoverStyle="color:var(--orange)" onClick={() => navigate("/rebased")}
|
||||
><Swords />{$text.nav.eventsPages.fresh}</Button
|
||||
><Swords />{$text.eventsPages.fresh}</Button
|
||||
>
|
||||
<Button class="rounded-[5px] bg-transparent" buttonHoverStyle="color:var(--orange)" onClick={() => navigate("https://asikarikas.ee/", { external: true })}
|
||||
><Trophy />ASI Karikas</Button
|
||||
>
|
||||
<Button class="rounded-[5px] bg-transparent" buttonHoverStyle="color:var(--orange)" onClick={() => navigate("https://remondikohvik.lapikud.ee/", { external: true })}
|
||||
><Coffee />{$text.nav.eventsPages.repair}</Button
|
||||
><Coffee />{$text.eventsPages.repair}</Button
|
||||
>
|
||||
</Dropdown>
|
||||
<Button buttonHoverStyle="background-color:var(--orange); color:var(--black)" class="rounded-[5px]" onClick={() => navigate("/kontakt")}
|
||||
>{$text.nav.contact}
|
||||
>{$text.contact}
|
||||
</Button>
|
||||
<Button buttonHoverStyle="background-color:var(--orange); color:var(--black)" class="rounded-[5px]" onClick={() => navigate("/helpdesk")}
|
||||
>{$text.nav.helpdesk}
|
||||
>{$text.helpdesk}
|
||||
</Button>
|
||||
|
||||
<!-- Language Switcher -->
|
||||
<Button
|
||||
class="rounded-[5px] px-3 py-1 text-sm ml-2"
|
||||
style="color: var(--orange)"
|
||||
buttonHoverStyle="background-color:var(--orange); color:var(--black)"
|
||||
onClick={() => switchLanguageRoute($currentLang === 'est' ? 'en' : 'est')}
|
||||
>
|
||||
{$currentLang === 'est' ? 'EN' : 'EST'}
|
||||
</Button>
|
||||
</nav>
|
||||
|
||||
<!-- Mobile Hamburger Button -->
|
||||
<Button
|
||||
onClick={toggleMobileMenu}
|
||||
class="md:hidden ml-auto p-2 text-white hover:text-orange-500 transition-colors bg-transparent"
|
||||
class="md:hidden ml-auto p-2 text-white transition-colors bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
style="opacity: {mobileMenuOpen ? '0' : '1'}; pointer-events: {mobileMenuOpen ? 'none' : 'auto'};"
|
||||
aria-label="Toggle menu"
|
||||
>
|
||||
@@ -164,87 +180,97 @@
|
||||
<div class="absolute top-8 right-0 px-(--site-padding)">
|
||||
<Button
|
||||
onClick={closeMobileMenu}
|
||||
class="ml-auto p-2 hover:text-orange-500 transition-colors flex bg-transparent"
|
||||
class="ml-auto p-2 transition-colors flex bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
aria-label="Close menu"
|
||||
>
|
||||
<X size={32} color="white" class="hover:stroke-orange-500" />
|
||||
<X size={32} color="white" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<!-- Menu Content -->
|
||||
<Stack gap="var(--space-5)" className="flex-1 px-8 pb-8 text-white text-xl justify-center">
|
||||
<!-- About Section -->
|
||||
<Stack gap="var(--space-3)" className="border-b border-gray-700 pb-4">
|
||||
<h3 class="text-2xl font-bold text-orange-500">{$text.nav.about}</h3>
|
||||
<Stack gap="var(--space-3)">
|
||||
<h3 class="text-2xl font-bold" style="color: var(--orange)">{$text.about}</h3>
|
||||
<Stack gap="var(--space-2)" className="pl-4">
|
||||
<Button
|
||||
onClick={() => handleNavigation("/mis-teeme")}
|
||||
class="text-left hover:text-orange-500 transition-colors flex items-center gap-2 bg-transparent"
|
||||
onClick={() => handleNavigation("/lapikutest")}
|
||||
class="text-left transition-colors flex items-center gap-2 bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
>
|
||||
{$text.nav.aboutPages.info}
|
||||
{$text.aboutPages.info}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleNavigation("/liitu-meiega")}
|
||||
class="text-left hover:text-orange-500 transition-colors flex items-center gap-2 bg-transparent"
|
||||
onClick={() => handleNavigation("/tudengile")}
|
||||
class="text-left transition-colors flex items-center gap-2 bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
>
|
||||
<Bot size={20} />
|
||||
{$text.nav.aboutPages.join}
|
||||
{$text.aboutPages.join}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleNavigation("/mentorid")}
|
||||
class="text-left hover:text-orange-500 transition-colors flex items-center gap-2 bg-transparent"
|
||||
class="text-left transition-colors flex items-center gap-2 bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
>
|
||||
<HandHeart size={20} />
|
||||
{$text.nav.aboutPages.mentors}
|
||||
{$text.aboutPages.mentors}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleNavigation("/juhatus")}
|
||||
class="text-left hover:text-orange-500 transition-colors flex items-center gap-2 bg-transparent"
|
||||
onClick={() => handleNavigation("/ettevottele")}
|
||||
class="text-left transition-colors flex items-center gap-2 bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
>
|
||||
<Lectern size={20} />
|
||||
{$text.nav.aboutPages.board}
|
||||
Ettevõttele
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<!-- Events Section -->
|
||||
<Stack gap="var(--space-3)" className="border-b border-gray-700 pb-4">
|
||||
<h3 class="text-2xl font-bold text-orange-500">{$text.nav.events}</h3>
|
||||
<Stack gap="var(--space-3)" >
|
||||
<h3 class="text-2xl font-bold" style="color: var(--orange)">{$text.events}</h3>
|
||||
<Stack gap="var(--space-2)" className="pl-4">
|
||||
<Button
|
||||
onClick={() => handleNavigation("/kalender")}
|
||||
class="text-left hover:text-orange-500 transition-colors flex items-center gap-2 bg-transparent"
|
||||
class="text-left transition-colors flex items-center gap-2 bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
>
|
||||
<CalendarClock size={20} />
|
||||
{$text.nav.eventsPages.calendar}
|
||||
{$text.eventsPages.calendar}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleNavigation("/mentorid")}
|
||||
class="text-left hover:text-orange-500 transition-colors flex items-center gap-2 bg-transparent"
|
||||
class="text-left transition-colors flex items-center gap-2 bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
>
|
||||
<Presentation size={20} />
|
||||
{$text.nav.eventsPages.workshops}
|
||||
{$text.eventsPages.workshops}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleNavigation("/rebased")}
|
||||
class="text-left hover:text-orange-500 transition-colors flex items-center gap-2 bg-transparent"
|
||||
class="text-left transition-colors flex items-center gap-2 bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
>
|
||||
<Swords size={20} />
|
||||
{$text.nav.eventsPages.fresh}
|
||||
{$text.eventsPages.fresh}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleNavigation("https://asikarikas.ee/", { external: true })}
|
||||
class="text-left hover:text-orange-500 transition-colors flex items-center gap-2 bg-transparent"
|
||||
class="text-left transition-colors flex items-center gap-2 bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
>
|
||||
<Trophy size={20} />
|
||||
ASI Karikas
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleNavigation("https://remondikohvik.lapikud.ee/", { external: true })}
|
||||
class="text-left hover:text-orange-500 transition-colors flex items-center gap-2 bg-transparent"
|
||||
class="text-left transition-colors flex items-center gap-2 bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
>
|
||||
<Coffee size={20} />
|
||||
{$text.nav.eventsPages.repair}
|
||||
{$text.eventsPages.repair}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
@@ -253,18 +279,31 @@
|
||||
<Stack gap="var(--space-3)">
|
||||
<Button
|
||||
onClick={() => handleNavigation("/kontakt")}
|
||||
class="text-left text-2xl font-semibold hover:text-orange-500 transition-colors bg-transparent"
|
||||
class="text-left text-2xl font-semibold transition-colors bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
>
|
||||
{$text.nav.contact}
|
||||
{$text.contact}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleNavigation("/helpdesk")}
|
||||
class="text-left text-2xl font-semibold hover:text-orange-500 transition-colors bg-transparent"
|
||||
class="text-left text-2xl font-semibold transition-colors bg-transparent"
|
||||
buttonHoverStyle="color: var(--orange)"
|
||||
>
|
||||
{$text.nav.helpdesk}
|
||||
{$text.helpdesk}
|
||||
</Button>
|
||||
</Stack>
|
||||
<!-- Language Switcher -->
|
||||
<Stack gap="var(--space-3)">
|
||||
<Button
|
||||
class="w-full rounded-lg py-3 text-lg"
|
||||
style="background-color: var(--orange); color: var(--black)"
|
||||
onClick={() => handleLanguageSwitch($currentLang === 'est' ? 'en' : 'est')}
|
||||
>
|
||||
{$currentLang === 'est' ? 'English' : 'Eesti'}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -1,26 +1,52 @@
|
||||
import { writable } from 'svelte/store';
|
||||
import { getLanguageFromRoute } from '../routes';
|
||||
|
||||
// Load saved language or default to 'est'
|
||||
const savedLang = typeof window !== 'undefined'
|
||||
? localStorage.getItem('language') || 'est'
|
||||
: 'est';
|
||||
// Get initial language from URL or localStorage
|
||||
function getInitialLanguage() {
|
||||
if (typeof window === 'undefined') return 'est';
|
||||
|
||||
const path = window.location.pathname;
|
||||
const langFromRoute = getLanguageFromRoute(path);
|
||||
|
||||
// If we detected a language from route, use it and save it
|
||||
if (langFromRoute) {
|
||||
localStorage.setItem('language', langFromRoute);
|
||||
return langFromRoute;
|
||||
}
|
||||
|
||||
// Otherwise use saved language or default to 'est'
|
||||
return localStorage.getItem('language') || 'est';
|
||||
}
|
||||
|
||||
export const currentLang = writable(savedLang);
|
||||
const initialLang = getInitialLanguage();
|
||||
|
||||
export const currentLang = writable(initialLang);
|
||||
|
||||
// Store for translations
|
||||
export const text = writable({});
|
||||
|
||||
async function loadTranslations(lang) {
|
||||
try {
|
||||
const response = await fetch(`/locales/${lang}.json`);
|
||||
const data = await response.json();
|
||||
text.set(data);
|
||||
const translations = {};
|
||||
|
||||
// Dynamically import all translation files for the specific language
|
||||
// Vite will code-split these and only bundle the ones actually used
|
||||
const modules = import.meta.glob('/src/locales/*/*.json');
|
||||
|
||||
for (const path in modules) {
|
||||
if (path.includes(`/locales/${lang}/`)) {
|
||||
const module = await modules[path]();
|
||||
Object.assign(translations, module.default || module);
|
||||
}
|
||||
}
|
||||
|
||||
text.set(translations);
|
||||
} catch (error) {
|
||||
console.error(`Failed to load translations for ${lang}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
loadTranslations(savedLang);
|
||||
loadTranslations(initialLang);
|
||||
|
||||
export function switchLang(lang) {
|
||||
currentLang.set(lang);
|
||||
@@ -28,4 +54,15 @@ export function switchLang(lang) {
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem('language', lang);
|
||||
}
|
||||
}
|
||||
|
||||
// Update language when route changes
|
||||
if (typeof window !== 'undefined') {
|
||||
window.addEventListener('popstate', () => {
|
||||
const path = window.location.pathname;
|
||||
const lang = getLanguageFromRoute(path);
|
||||
if (lang) {
|
||||
switchLang(lang);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
export { navigate, goBack, reload, getPath, getQuery } from './router/router.js';
|
||||
export { navigate, goBack, reload, getPath, getQuery, switchLanguageRoute } from './router/router.js';
|
||||
export { default as Router } from './router/Router.svelte';
|
||||
|
||||
export { currentLang, text, switchLang } from './i18n.js';
|
||||
export { currentLang, text, switchLang } from './i18n.js';
|
||||
export { getLangText } from './langHelpers.js';
|
||||
17
src/lib/langHelpers.js
Normal file
17
src/lib/langHelpers.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Helper function to get text with fallback to Estonian
|
||||
export function getLangText(item, key, lang = 'est') {
|
||||
const value = item[key];
|
||||
|
||||
// If it's a simple string, return it
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
}
|
||||
|
||||
// If it's an object with language keys
|
||||
if (value && typeof value === 'object') {
|
||||
// Try to get the requested language, fallback to Estonian
|
||||
return value[lang] || value.est || '';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
@@ -1,14 +1,43 @@
|
||||
import { getTranslatedRoute, getLanguageFromRoute } from '../../routes';
|
||||
import { switchLang } from '../i18n.js';
|
||||
|
||||
/**
|
||||
* Navigate to a path (internal or external)
|
||||
* @param {string} path - The path or URL to navigate to
|
||||
* @param {boolean} external - Whether this is an external link (default: false)
|
||||
* @param {Object} options - Navigation options
|
||||
* @param {boolean} options.external - Whether this is an external link
|
||||
*/
|
||||
export function navigate(path, external = false) {
|
||||
export function navigate(path, options = {}) {
|
||||
const { external = false } = options;
|
||||
|
||||
if (external) {
|
||||
window.location.href = path;
|
||||
} else {
|
||||
window.history.pushState({}, "", path);
|
||||
window.dispatchEvent(new PopStateEvent('popstate'));
|
||||
|
||||
// Update language based on new route
|
||||
const lang = getLanguageFromRoute(path);
|
||||
if (lang) {
|
||||
switchLang(lang);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch language and navigate to translated route
|
||||
* @param {string} targetLang - Target language ('est' or 'en')
|
||||
*/
|
||||
export function switchLanguageRoute(targetLang) {
|
||||
const currentPath = window.location.pathname;
|
||||
const translatedPath = getTranslatedRoute(currentPath, targetLang);
|
||||
|
||||
// Always update the language first
|
||||
switchLang(targetLang);
|
||||
|
||||
// Only navigate if the path is different
|
||||
if (translatedPath !== currentPath) {
|
||||
navigate(translatedPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
7
src/locales/en/Footer.json
Normal file
7
src/locales/en/Footer.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"address": "Address: ",
|
||||
"mail": "E-mail: ",
|
||||
"messenger": "Messenger: ",
|
||||
"reg": "Reg. code: ",
|
||||
"socials": "Social Media"
|
||||
}
|
||||
1
src/locales/en/Home.json
Normal file
1
src/locales/en/Home.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
18
src/locales/en/Navbar.json
Normal file
18
src/locales/en/Navbar.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"about": "About Us",
|
||||
"aboutPages": {
|
||||
"info": "What we're doing?",
|
||||
"join": "Join Us",
|
||||
"mentors": "Mentors",
|
||||
"board": "Board"
|
||||
},
|
||||
"events": "Events",
|
||||
"eventsPages": {
|
||||
"calendar": "Events Calendar",
|
||||
"workshops": "Workshops",
|
||||
"fresh": "Freshmen Initiation",
|
||||
"repair": "Repair Café"
|
||||
},
|
||||
"contact": "Contact",
|
||||
"helpdesk": "Helpdesk"
|
||||
}
|
||||
7
src/locales/est/Footer.json
Normal file
7
src/locales/est/Footer.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"address": "Aadress: ",
|
||||
"mail": "E-post: ",
|
||||
"messenger": "Messenger: ",
|
||||
"reg": "Reg. kood: ",
|
||||
"socials": "Sotsiaalmeedia"
|
||||
}
|
||||
1
src/locales/est/Home.json
Normal file
1
src/locales/est/Home.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
18
src/locales/est/Navbar.json
Normal file
18
src/locales/est/Navbar.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"about": "Meist",
|
||||
"aboutPages": {
|
||||
"info": "Mis Teeme?",
|
||||
"join": "Liitu Meiega",
|
||||
"mentors": "Mentorid",
|
||||
"board": "Juhatus"
|
||||
},
|
||||
"events": "Üritused",
|
||||
"eventsPages": {
|
||||
"calendar": "Ürituste Kalender",
|
||||
"workshops": "Koolitused",
|
||||
"fresh": "Rebaste Ristimine",
|
||||
"repair": "Remondikohvik"
|
||||
},
|
||||
"contact": "Kontakt",
|
||||
"helpdesk": "Helpdesk"
|
||||
}
|
||||
274
src/routes/AboutUs.svelte
Normal file
274
src/routes/AboutUs.svelte
Normal file
@@ -0,0 +1,274 @@
|
||||
<script>
|
||||
import {
|
||||
Section,
|
||||
Grid,
|
||||
Card,
|
||||
Center,
|
||||
} from "$components";
|
||||
import { onMount } from "svelte";
|
||||
import yaml from 'js-yaml';
|
||||
import { currentLang, getLangText } from "$lib";
|
||||
|
||||
import Users from "lucide-svelte/icons/users";
|
||||
import History from "lucide-svelte/icons/history";
|
||||
import Target from "lucide-svelte/icons/target";
|
||||
import Heart from "lucide-svelte/icons/heart";
|
||||
import Award from "lucide-svelte/icons/award";
|
||||
import Sparkles from "lucide-svelte/icons/sparkles";
|
||||
import Mail from "lucide-svelte/icons/mail";
|
||||
import Phone from "lucide-svelte/icons/phone";
|
||||
|
||||
let management = [];
|
||||
let pastManagement = [];
|
||||
|
||||
onMount(async () => {
|
||||
const [mgmtResponse, pastResponse] = await Promise.all([
|
||||
fetch('/_data/management.yml'),
|
||||
fetch('/_data/past_management.yml')
|
||||
]);
|
||||
|
||||
const [mgmtText, pastText] = await Promise.all([
|
||||
mgmtResponse.text(),
|
||||
pastResponse.text()
|
||||
]);
|
||||
|
||||
management = yaml.load(mgmtText);
|
||||
pastManagement = yaml.load(pastText);
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<Section background="orange">
|
||||
<Center>
|
||||
<div class="text-center max-w-4xl">
|
||||
<h1 class="text-5xl font-bold mb-6">Kes me oleme?</h1>
|
||||
<p class="text-2xl leading-relaxed">
|
||||
MTÜ Lapikud on Tallinna Tehnikaülikooli Tarkvaraarendusklubi,
|
||||
mis ühendab endisi ja praegusi IT huvilisi tudengeid
|
||||
</p>
|
||||
</div>
|
||||
</Center>
|
||||
</Section>
|
||||
|
||||
<!-- History Section -->
|
||||
<Section>
|
||||
<Grid gap="var(--space-5)">
|
||||
<Card variant="glass">
|
||||
<div class="flex items-center gap-4 mb-6">
|
||||
<div class="feature-icon" style="color: var(--orange)">
|
||||
<History size={32} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h2 class="text-4xl font-bold">Meie lugu</h2>
|
||||
</div>
|
||||
<div class="space-y-4 text-lg">
|
||||
<p>
|
||||
Organisatsioon loodi <strong>2002. aastal</strong> informaatika tudengite poolt,
|
||||
kelle erialatunnuseks oli "LAP". Targad mehed otsustasid, et järelikult on nad "Lapikud".
|
||||
</p>
|
||||
<p>
|
||||
Üle 20 aasta oleme kasvanud väikesest tudengite grupist suureks kogukonnaks,
|
||||
mis on aidanud sadadel tudengitel saada väärtuslikku kogemust IT-valdkonnas.
|
||||
</p>
|
||||
<p>
|
||||
Täna oleme uhked oma traditsiooni üle ja jätkame sellega,
|
||||
et pakkuda tudengitele võimalusi areneda ja kasvada.
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="flex items-center gap-4 mb-6">
|
||||
<div class="feature-icon" style="color: var(--orange)">
|
||||
<Target size={32} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h2 class="text-4xl font-bold">Meie eesmärk</h2>
|
||||
</div>
|
||||
<div class="space-y-4 text-lg">
|
||||
<p>
|
||||
Meie põhieesmärgiks on Tallinna Tehnikaülikooli IT tudengitele
|
||||
<strong>erialase lisandväärtuse loomine</strong>.
|
||||
</p>
|
||||
<p>
|
||||
Kaasame tudengeid huvitavatesse IT projektidesse ning anname tudengitele võimaluse
|
||||
midagi reaalset oma käega ära teha. Aktiivsetel tudengitel on võimalus saada meie juures esimene töökogemus.
|
||||
</p>
|
||||
<p>
|
||||
Meie projektidest kooruvad välja huvitavad ja tarvilikud lõputööd ning
|
||||
meie liikmeskonnast on tulnud ka lõputöö juhendajaid.
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- Values Section -->
|
||||
<Section background="neutral">
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-4xl font-bold mb-4">Meie väärtused</h2>
|
||||
<p class="text-xl text-gray-600">Mis meile oluline on</p>
|
||||
</div>
|
||||
|
||||
<Grid columns={3} gap="var(--space-5)">
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<Users size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">Kogukond</h3>
|
||||
<p class="text-gray-600">
|
||||
Oleme tugev kogukond, kus iga liige on oluline. Toetame ja aitame üksteist.
|
||||
</p>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<Award size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">Kvaliteet</h3>
|
||||
<p class="text-gray-600">
|
||||
Teeme tööd südamega ja püüdleme alati parima tulemuse poole.
|
||||
</p>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<Sparkles size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">Innovatsioon</h3>
|
||||
<p class="text-gray-600">
|
||||
Kasutame uusimaid tehnoloogiaid ja otsime alati paremaid lahendusi.
|
||||
</p>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<Heart size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">Kirg</h3>
|
||||
<p class="text-gray-600">
|
||||
Teeme seda, mida armastame. Meie kirglikud liikmed on meie tugevus.
|
||||
</p>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<Users size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">Kaasamine</h3>
|
||||
<p class="text-gray-600">
|
||||
Kaasame kõiki teaduskondi - IT, majandus, inseneeria ja muud.
|
||||
</p>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<Target size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">Praktiline</h3>
|
||||
<p class="text-gray-600">
|
||||
Teeme reaalset tööd, mis annab tudengitele praktilist kogemust.
|
||||
</p>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- Current Management -->
|
||||
<Section>
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-4xl font-bold mb-4">Meie juhatus</h2>
|
||||
<p class="text-xl text-gray-600">Inimesed, kes viivad organisatsiooni edasi</p>
|
||||
</div>
|
||||
|
||||
<Grid columns={2} gap="var(--space-6)">
|
||||
{#each management as person}
|
||||
<Card variant="glass">
|
||||
<div class="flex flex-col md:flex-row gap-6">
|
||||
{#if person.photo}
|
||||
<div class="shrink-0">
|
||||
<img
|
||||
src={`/assets/management-images/${person.photo}`}
|
||||
alt={person.name}
|
||||
class="w-full md:w-48 h-48 object-cover rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="flex-1">
|
||||
<h3 class="text-2xl font-bold mb-2">{person.name}</h3>
|
||||
<p class="text-lg font-semibold mb-2" style="color: var(--orange)">
|
||||
{getLangText(person, 'role', $currentLang)}
|
||||
</p>
|
||||
{#if person.subrole}
|
||||
<p class="text-gray-600 mb-4">{getLangText(person, 'subrole', $currentLang)}</p>
|
||||
{/if}
|
||||
|
||||
<div class="space-y-2">
|
||||
{#if person.email}
|
||||
<div class="flex items-center gap-2">
|
||||
<Mail size={18} style="color: var(--orange)" />
|
||||
<a href={`mailto:${person.email}`} class="hover:underline">
|
||||
{person.email}
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
{#if person.phone}
|
||||
<div class="flex items-center gap-2">
|
||||
<Phone size={18} style="color: var(--orange)" />
|
||||
<a href={`tel:${person.phone}`} class="hover:underline">
|
||||
{person.phone}
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
{/each}
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- Past Management -->
|
||||
{#if pastManagement && pastManagement.length > 0}
|
||||
<Section background="neutral">
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-4xl font-bold mb-4">Endised juhatused</h2>
|
||||
<p class="text-xl text-gray-600">Täname kõiki, kes on organisatsiooni juhtinud</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-12">
|
||||
{#each pastManagement as yearGroup}
|
||||
<div>
|
||||
<h3 class="text-3xl font-bold mb-6 text-center">{yearGroup.year}</h3>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-6">
|
||||
{#each yearGroup.members as member}
|
||||
<Card variant="glass" class="text-center">
|
||||
{#if member.image}
|
||||
<img
|
||||
src={`/assets/past-management-images/optimised/${member.image}`}
|
||||
alt={member.name}
|
||||
class="w-full h-32 object-cover rounded-lg mb-3"
|
||||
on:error={(e) => {
|
||||
e.target.src = '/assets/past-management-images/original/' + member.image;
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
<p class="font-semibold">{member.name}</p>
|
||||
</Card>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Section>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.feature-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: rgba(255, 127, 0, 0.1);
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
313
src/routes/Contact.svelte
Normal file
313
src/routes/Contact.svelte
Normal file
@@ -0,0 +1,313 @@
|
||||
<script>
|
||||
import {
|
||||
Section,
|
||||
Grid,
|
||||
Card,
|
||||
Center,
|
||||
} from "$components";
|
||||
|
||||
import MapPin from "lucide-svelte/icons/map-pin";
|
||||
import Mail from "lucide-svelte/icons/mail";
|
||||
import Phone from "lucide-svelte/icons/phone";
|
||||
import MessageCircle from "lucide-svelte/icons/message-circle";
|
||||
import Facebook from "lucide-svelte/icons/facebook";
|
||||
import Instagram from "lucide-svelte/icons/instagram";
|
||||
import Github from "lucide-svelte/icons/github";
|
||||
import Building from "lucide-svelte/icons/building";
|
||||
import Clock from "lucide-svelte/icons/clock";
|
||||
|
||||
const contactMethods = [
|
||||
{
|
||||
icon: MapPin,
|
||||
title: "Aadress",
|
||||
content: "Akadeemia tee 5, 12616 Tallinn",
|
||||
subtitle: "ICT-teaduskond, Raja 15 ruum 111",
|
||||
link: "https://goo.gl/maps/..."
|
||||
},
|
||||
{
|
||||
icon: Mail,
|
||||
title: "E-post",
|
||||
content: "lapikud@lapikud.ee",
|
||||
link: "mailto:lapikud@lapikud.ee"
|
||||
},
|
||||
{
|
||||
icon: Phone,
|
||||
title: "Telefon",
|
||||
content: "+372 58 160 799",
|
||||
link: "tel:+37258160799"
|
||||
},
|
||||
{
|
||||
icon: MessageCircle,
|
||||
title: "Messenger",
|
||||
content: "m.me/Lapikud",
|
||||
link: "https://m.me/Lapikud"
|
||||
}
|
||||
];
|
||||
|
||||
const socialMedia = [
|
||||
{
|
||||
icon: Facebook,
|
||||
name: "Facebook",
|
||||
link: "https://www.facebook.com/Lapikud/"
|
||||
},
|
||||
{
|
||||
icon: Instagram,
|
||||
name: "Instagram",
|
||||
link: "https://www.instagram.com/lapikud/"
|
||||
},
|
||||
{
|
||||
icon: Github,
|
||||
name: "GitHub",
|
||||
link: "https://github.com/Lapikud/"
|
||||
}
|
||||
];
|
||||
|
||||
const organizationInfo = [
|
||||
{
|
||||
icon: Building,
|
||||
title: "Registrikood",
|
||||
content: "80167145"
|
||||
},
|
||||
{
|
||||
icon: Building,
|
||||
title: "Pangakonto",
|
||||
content: "EE812200221019551756",
|
||||
subtitle: "Swedbank"
|
||||
}
|
||||
];
|
||||
|
||||
let formData = {
|
||||
name: '',
|
||||
email: '',
|
||||
subject: '',
|
||||
message: ''
|
||||
};
|
||||
|
||||
function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
// Create mailto link with form data
|
||||
const mailtoLink = `mailto:lapikud@lapikud.ee?subject=${encodeURIComponent(formData.subject)}&body=${encodeURIComponent(`Nimi: ${formData.name}\nE-post: ${formData.email}\n\nSõnum:\n${formData.message}`)}`;
|
||||
window.location.href = mailtoLink;
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<Section background="orange">
|
||||
<Center>
|
||||
<div class="text-center max-w-4xl">
|
||||
<h1 class="text-5xl font-bold mb-6">Võta ühendust</h1>
|
||||
<p class="text-2xl leading-relaxed">
|
||||
Kas sul on küsimusi? Tahad liituda? Või soovid alustada koostööd? Võta julgelt ühendust!
|
||||
</p>
|
||||
</div>
|
||||
</Center>
|
||||
</Section>
|
||||
|
||||
<!-- Contact Methods -->
|
||||
<Section>
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-4xl font-bold mb-4">Kuidas meiega ühendust võtta?</h2>
|
||||
<p class="text-xl text-gray-600">Vali endale sobiv viis</p>
|
||||
</div>
|
||||
|
||||
<Grid columns={2} gap="var(--space-5)">
|
||||
{#each contactMethods as method}
|
||||
<Card variant="glass">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="feature-icon shrink-0" style="color: var(--orange)">
|
||||
<svelte:component this={method.icon} size={32} strokeWidth={1.5} />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h3 class="text-xl font-bold mb-2">{method.title}</h3>
|
||||
{#if method.link}
|
||||
<a
|
||||
href={method.link}
|
||||
class="text-lg hover:underline"
|
||||
style="color: var(--orange)"
|
||||
target={method.link.startsWith('http') ? '_blank' : '_self'}
|
||||
rel={method.link.startsWith('http') ? 'noopener noreferrer' : ''}
|
||||
>
|
||||
{method.content}
|
||||
</a>
|
||||
{:else}
|
||||
<p class="text-lg">{method.content}</p>
|
||||
{/if}
|
||||
{#if method.subtitle}
|
||||
<p class="text-gray-600 text-sm mt-1">{method.subtitle}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
{/each}
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- Contact Form -->
|
||||
<Section background="neutral">
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<div class="text-center mb-8">
|
||||
<h2 class="text-4xl font-bold mb-4">Saada meile sõnum</h2>
|
||||
<p class="text-xl text-gray-600">Täida vorm ja me võtame sinuga ühendust</p>
|
||||
</div>
|
||||
|
||||
<Card variant="glass">
|
||||
<form on:submit={handleSubmit} class="space-y-6">
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-semibold mb-2">Nimi *</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
bind:value={formData.name}
|
||||
required
|
||||
class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-orange-500 focus:ring-2 focus:ring-orange-200 outline-none transition"
|
||||
placeholder="Sinu nimi"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-semibold mb-2">E-post *</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
bind:value={formData.email}
|
||||
required
|
||||
class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-orange-500 focus:ring-2 focus:ring-orange-200 outline-none transition"
|
||||
placeholder="sinu@email.ee"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="subject" class="block text-sm font-semibold mb-2">Teema *</label>
|
||||
<input
|
||||
type="text"
|
||||
id="subject"
|
||||
bind:value={formData.subject}
|
||||
required
|
||||
class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-orange-500 focus:ring-2 focus:ring-orange-200 outline-none transition"
|
||||
placeholder="Sõnumi teema"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="message" class="block text-sm font-semibold mb-2">Sõnum *</label>
|
||||
<textarea
|
||||
id="message"
|
||||
bind:value={formData.message}
|
||||
required
|
||||
rows="6"
|
||||
class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:border-orange-500 focus:ring-2 focus:ring-orange-200 outline-none transition resize-none"
|
||||
placeholder="Kirjuta oma sõnum siia..."
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="w-full py-3 px-6 bg-orange-500 hover:bg-orange-600 text-white font-semibold rounded-lg transition-colors"
|
||||
>
|
||||
Saada sõnum
|
||||
</button>
|
||||
</form>
|
||||
</Card>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<!-- Office Hours & Location -->
|
||||
<Section>
|
||||
<Grid gap="var(--space-5)">
|
||||
<Card variant="glass">
|
||||
<div class="flex items-start gap-4 mb-4">
|
||||
<div class="feature-icon" style="color: var(--orange)">
|
||||
<Clock size={32} strokeWidth={1.5} />
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-3xl font-bold mb-4">Lahtiolekuajad</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-3 text-lg">
|
||||
<div class="flex justify-between">
|
||||
<span class="font-semibold">Esmaspäev - Reede:</span>
|
||||
<span>10:00 - 16:00</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="font-semibold">Laupäev - Pühapäev:</span>
|
||||
<span>Suletud</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 mt-4">
|
||||
* Soovitame enne külastamist võtta ühendust, et vältida ootamist
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="flex items-start gap-4 mb-4">
|
||||
<div class="feature-icon" style="color: var(--orange)">
|
||||
<MapPin size={32} strokeWidth={1.5} />
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-3xl font-bold mb-4">Kuidas meid leida?</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-3 text-lg">
|
||||
<p><strong>Aadress:</strong> Akadeemia tee 5, 12616 Tallinn</p>
|
||||
<p><strong>Hoone:</strong> ICT-teaduskond (Raja 15)</p>
|
||||
<p><strong>Ruum:</strong> 111</p>
|
||||
<p class="text-sm text-gray-600 mt-4">
|
||||
Asume Tallinna Tehnikaülikooli ICT-teaduskonna hoones.
|
||||
Kui tuled ühistranspordiga, on lähimad peatused "Mustakivi" ja "Tehnikaülikool".
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- Social Media & Legal Info -->
|
||||
<Section background="neutral">
|
||||
<Grid gap="var(--space-5)">
|
||||
<Card variant="glass">
|
||||
<h2 class="text-3xl font-bold mb-6 text-center">Jälgi meid sotsiaalmeedias</h2>
|
||||
<div class="flex flex-wrap justify-center gap-4">
|
||||
{#each socialMedia as social}
|
||||
<a
|
||||
href={social.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="flex items-center gap-3 px-6 py-3 bg-orange-100 hover:bg-orange-200 rounded-lg transition-colors"
|
||||
>
|
||||
<svelte:component this={social.icon} size={24} style="color: var(--orange)" />
|
||||
<span class="font-semibold">{social.name}</span>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<h2 class="text-3xl font-bold mb-6 text-center">MTÜ Lapikud</h2>
|
||||
<div class="space-y-3">
|
||||
{#each organizationInfo as info}
|
||||
<div class="flex items-start gap-4">
|
||||
<svelte:component this={info.icon} size={24} style="color: var(--orange)" />
|
||||
<div>
|
||||
<p class="font-semibold">{info.title}</p>
|
||||
<p class="text-gray-700">{info.content}</p>
|
||||
{#if info.subtitle}
|
||||
<p class="text-sm text-gray-600">{info.subtitle}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<style>
|
||||
.feature-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
background: rgba(255, 127, 0, 0.1);
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
245
src/routes/Helpdesk.svelte
Normal file
245
src/routes/Helpdesk.svelte
Normal file
@@ -0,0 +1,245 @@
|
||||
<script>
|
||||
import {
|
||||
Section,
|
||||
Grid,
|
||||
Card,
|
||||
Center,
|
||||
} from "$components";
|
||||
|
||||
import Laptop from "lucide-svelte/icons/laptop";
|
||||
import Smartphone from "lucide-svelte/icons/smartphone";
|
||||
import HardDrive from "lucide-svelte/icons/hard-drive";
|
||||
import Wifi from "lucide-svelte/icons/wifi";
|
||||
import Settings from "lucide-svelte/icons/settings";
|
||||
import Wrench from "lucide-svelte/icons/wrench";
|
||||
import Clock from "lucide-svelte/icons/clock";
|
||||
import MapPin from "lucide-svelte/icons/map-pin";
|
||||
import Mail from "lucide-svelte/icons/mail";
|
||||
import Phone from "lucide-svelte/icons/phone";
|
||||
import CheckCircle from "lucide-svelte/icons/check-circle";
|
||||
|
||||
const services = [
|
||||
{
|
||||
icon: Laptop,
|
||||
title: "Arvuti diagnostika",
|
||||
description: "Tuvastame riistvara- ja tarkvaraprobleemid ning pakume lahendusi",
|
||||
price: "Alates 10€"
|
||||
},
|
||||
{
|
||||
icon: Settings,
|
||||
title: "Operatsioonisüsteemi paigaldus",
|
||||
description: "Windows, Linux või macOS paigaldamine ja seadistamine",
|
||||
price: "20€"
|
||||
},
|
||||
{
|
||||
icon: HardDrive,
|
||||
title: "Riistvara vahetus",
|
||||
description: "RAM, SSD, HDD või muu komponendi vahetus ja paigaldus",
|
||||
price: "Vastavalt tööle"
|
||||
},
|
||||
{
|
||||
icon: Wrench,
|
||||
title: "Arvuti puhastus",
|
||||
description: "Füüsiline puhastus tolmust ja termopasta vahetus",
|
||||
price: "15€"
|
||||
},
|
||||
{
|
||||
icon: Wifi,
|
||||
title: "Võrgu seadistamine",
|
||||
description: "Koduvõrgu või WiFi seadistamine ja probleemide lahendamine",
|
||||
price: "15€"
|
||||
},
|
||||
{
|
||||
icon: Smartphone,
|
||||
title: "Nutiseadmete abi",
|
||||
description: "Nutitelefonide ja tahvelarvutite seadistamine ja nõustamine",
|
||||
price: "10€"
|
||||
}
|
||||
];
|
||||
|
||||
const whyChooseUs = [
|
||||
"Tudengisõbralikud hinnad",
|
||||
"Kiire teenindus",
|
||||
"Kogenud meeskond",
|
||||
"Paindlikud lahtiolekuajad",
|
||||
"Garantii töödele",
|
||||
"Sõbralik teenindus"
|
||||
];
|
||||
</script>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<Section background="orange">
|
||||
<Center>
|
||||
<div class="text-center max-w-4xl">
|
||||
<h1 class="text-5xl font-bold mb-6">Helpdesk</h1>
|
||||
<p class="text-2xl leading-relaxed">
|
||||
Tudengisõbralik arvutiabiteenus. Aitame lahendada kõik sinu IT-mured!
|
||||
</p>
|
||||
</div>
|
||||
</Center>
|
||||
</Section>
|
||||
|
||||
<!-- Services Section -->
|
||||
<Section>
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-4xl font-bold mb-4">Meie teenused</h2>
|
||||
<p class="text-xl text-gray-600">Pakume laia valikut IT-teenuseid soodsa hinnaga</p>
|
||||
</div>
|
||||
|
||||
<Grid columns={3} gap="var(--space-5)">
|
||||
{#each services as service}
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<svelte:component this={service.icon} size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">{service.title}</h3>
|
||||
<p class="text-gray-600 mb-4">{service.description}</p>
|
||||
<p class="text-lg font-bold" style="color: var(--orange)">{service.price}</p>
|
||||
</Card>
|
||||
{/each}
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- Why Choose Us -->
|
||||
<Section background="neutral">
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-4xl font-bold mb-4">Miks valida meid?</h2>
|
||||
</div>
|
||||
|
||||
<Center>
|
||||
<Card variant="glass" class="max-w-4xl">
|
||||
<Grid columns={2} gap="var(--space-4)">
|
||||
{#each whyChooseUs as reason}
|
||||
<div class="flex items-center gap-3">
|
||||
<CheckCircle size={24} style="color: var(--orange)" />
|
||||
<span class="text-lg">{reason}</span>
|
||||
</div>
|
||||
{/each}
|
||||
</Grid>
|
||||
</Card>
|
||||
</Center>
|
||||
</Section>
|
||||
|
||||
<!-- Pricing Info -->
|
||||
<Section>
|
||||
<Grid gap="var(--space-5)">
|
||||
<Card variant="glass">
|
||||
<h2 class="text-4xl font-bold mb-6">Hinnakirjast</h2>
|
||||
<div class="space-y-4 text-lg">
|
||||
<p>
|
||||
Meie hinnad on tudengisõbralikud ja läbipaistvad. Enne töö alustamist teeme alati hinnapakkumise,
|
||||
et sa teaksid täpselt, mida oodata.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Diagnostika:</strong> Esimene diagnostika on tasuta! Maksad ainult siis, kui otsustad lasta meil
|
||||
probleem lahendada.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Töötunnid:</strong> Tavaline tunnitasu on 15€. Keerulisemad tööd võivad olla kallimad,
|
||||
kuid lepime alati kokku enne töö alustamist.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Varuosad:</strong> Varuosade hind lisandub töötasule. Aitame leida parimad hinnad ja kvaliteedi.
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<h2 class="text-4xl font-bold mb-6">Kuidas toimub teenindus?</h2>
|
||||
<div class="space-y-6">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="text-3xl font-bold" style="color: var(--orange)">1.</div>
|
||||
<div>
|
||||
<strong class="text-lg">Võta ühendust</strong><br/>
|
||||
Kirjuta meile või tule otse meie kontorisse. Kirjelda oma probleemi.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="text-3xl font-bold" style="color: var(--orange)">2.</div>
|
||||
<div>
|
||||
<strong class="text-lg">Diagnostika</strong><br/>
|
||||
Vaatame probleemi üle ja selgitame välja põhjuse. Teeme hinnapakkumise.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="text-3xl font-bold" style="color: var(--orange)">3.</div>
|
||||
<div>
|
||||
<strong class="text-lg">Remont</strong><br/>
|
||||
Kui oled nõus, alustame tööd. Hoiame sind kursis protsessiga.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="text-3xl font-bold" style="color: var(--orange)">4.</div>
|
||||
<div>
|
||||
<strong class="text-lg">Üleandmine</strong><br/>
|
||||
Anname arvuti üle, selgitame tehtud tööd ja anname nõu tulevikuks.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- Contact Section -->
|
||||
<Section background="orange">
|
||||
<Center>
|
||||
<div class="text-center max-w-4xl text-white">
|
||||
<h2 class="text-4xl font-bold mb-8">Võta ühendust</h2>
|
||||
|
||||
<Grid columns={2} gap="var(--space-6)">
|
||||
<Card variant="glass">
|
||||
<div class="mb-4">
|
||||
<MapPin size={32} class="mx-auto" />
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-2">Asukoht</h3>
|
||||
<p>Akadeemia tee 5</p>
|
||||
<p>12616 Tallinn</p>
|
||||
<p class="mt-2">ICT-teaduskond, Raja 15 ruum 111</p>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="mb-4">
|
||||
<Clock size={32} class="mx-auto" />
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-2">Lahtiolekuajad</h3>
|
||||
<p>Esmaspäev - Reede</p>
|
||||
<p>10:00 - 16:00</p>
|
||||
<p class="mt-2 text-sm">Võta ette ühendust, et vältida ootamist</p>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="mb-4">
|
||||
<Mail size={32} class="mx-auto" />
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-2">E-post</h3>
|
||||
<a href="mailto:erki@lapikud.ee" class="hover:underline">
|
||||
erki@lapikud.ee
|
||||
</a>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="mb-4">
|
||||
<Phone size={32} class="mx-auto" />
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-2">Telefon</h3>
|
||||
<a href="tel:+37259079190" class="hover:underline">
|
||||
+372 5907 9190
|
||||
</a>
|
||||
</Card>
|
||||
</Grid>
|
||||
</div>
|
||||
</Center>
|
||||
</Section>
|
||||
|
||||
<style>
|
||||
.feature-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: rgba(255, 127, 0, 0.1);
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
@@ -7,6 +7,7 @@
|
||||
Container,
|
||||
} from "$components";
|
||||
import { onMount } from "svelte";
|
||||
import yaml from 'js-yaml';
|
||||
|
||||
// Import Lucide icons
|
||||
import Wrench from "lucide-svelte/icons/wrench";
|
||||
@@ -18,8 +19,9 @@
|
||||
let partners = [];
|
||||
|
||||
onMount(async () => {
|
||||
const response = await fetch('/assets/partners/partners.json');
|
||||
partners = await response.json();
|
||||
const response = await fetch('/_data/partners.yml');
|
||||
const yamlText = await response.text();
|
||||
partners = yaml.load(yamlText);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -38,7 +40,7 @@
|
||||
|
||||
<Section>
|
||||
<Grid gap="var(--space-5)">
|
||||
<Card variant="animated-neutral" href="/liitu-meiega">
|
||||
<Card variant="animated-neutral" href="/tudengile">
|
||||
<div class="feature-icon" style="color: var(--orange)">
|
||||
<Users size={32} strokeWidth={1.5} />
|
||||
</div>
|
||||
@@ -106,7 +108,7 @@
|
||||
{#if partner.url}
|
||||
<a href={partner.url} target="_blank" rel="noopener noreferrer" class="partner-item" title={partner.name}>
|
||||
{#if partner.image}
|
||||
<img src="/assets/partners/{partner.image}" alt={partner.name} />
|
||||
<img src={`/assets/partners_logos/${partner.image}`} alt={partner.name} />
|
||||
{:else}
|
||||
<span class="partner-name">{partner.name}</span>
|
||||
{/if}
|
||||
@@ -114,7 +116,7 @@
|
||||
{:else}
|
||||
<div class="partner-item">
|
||||
{#if partner.image}
|
||||
<img src="/assets/partners/{partner.image}" alt={partner.name} />
|
||||
<img src={`/assets/partners_logos/${partner.image}`} alt={partner.name} />
|
||||
{:else}
|
||||
<span class="partner-name">{partner.name}</span>
|
||||
{/if}
|
||||
|
||||
176
src/routes/Mentors.svelte
Normal file
176
src/routes/Mentors.svelte
Normal file
@@ -0,0 +1,176 @@
|
||||
<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";
|
||||
|
||||
let mentors = [];
|
||||
|
||||
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 : '#';
|
||||
}
|
||||
</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>
|
||||
</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>
|
||||
{/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>
|
||||
</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>
|
||||
</Section>
|
||||
|
||||
<style>
|
||||
.line-clamp-3 {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
272
src/routes/OurWork.svelte
Normal file
272
src/routes/OurWork.svelte
Normal file
@@ -0,0 +1,272 @@
|
||||
<script>
|
||||
import {
|
||||
Section,
|
||||
Grid,
|
||||
Card,
|
||||
Center,
|
||||
} from "$components";
|
||||
import { onMount } from "svelte";
|
||||
import yaml from 'js-yaml';
|
||||
import { currentLang, getLangText } from "$lib";
|
||||
|
||||
import Rocket from "lucide-svelte/icons/rocket";
|
||||
import Users from "lucide-svelte/icons/users";
|
||||
import Target from "lucide-svelte/icons/target";
|
||||
import Briefcase from "lucide-svelte/icons/briefcase";
|
||||
import Code from "lucide-svelte/icons/code";
|
||||
import Smartphone from "lucide-svelte/icons/smartphone";
|
||||
import Globe from "lucide-svelte/icons/globe";
|
||||
import ArrowRight from "lucide-svelte/icons/arrow-right";
|
||||
import ExternalLink from "lucide-svelte/icons/external-link";
|
||||
|
||||
let projects = [];
|
||||
|
||||
onMount(async () => {
|
||||
const response = await fetch('/_data/ourwork.yml');
|
||||
const yamlText = await response.text();
|
||||
projects = yaml.load(yamlText).filter(p => p.title);
|
||||
});
|
||||
|
||||
const services = [
|
||||
{
|
||||
icon: Globe,
|
||||
title: "Veebilahendused",
|
||||
description: "Kaasaegsed ja responsiivsed veebilehed, mis toimivad igal seadmel"
|
||||
},
|
||||
{
|
||||
icon: Smartphone,
|
||||
title: "Mobiilirakendused",
|
||||
description: "iOS ja Android rakendused kasutajasõbralike liidestega"
|
||||
},
|
||||
{
|
||||
icon: Code,
|
||||
title: "Tarkvara arendus",
|
||||
description: "Kohandatud tarkvaralahendused teie ärivajadusteks"
|
||||
},
|
||||
{
|
||||
icon: Briefcase,
|
||||
title: "Konsultatsioon",
|
||||
description: "IT-nõustamine ja projekti planeerimine"
|
||||
}
|
||||
];
|
||||
|
||||
const whyUs = [
|
||||
{
|
||||
icon: Users,
|
||||
title: "Motiveeritud meeskond",
|
||||
description: "Meie tudengid on andekad, õhevil ja tahavad tõestada oma oskuseid"
|
||||
},
|
||||
{
|
||||
icon: Target,
|
||||
title: "Kvaliteetne tulemus",
|
||||
description: "Võtame iga projekti tõsiselt ja pingutame parima tulemuse nimel"
|
||||
},
|
||||
{
|
||||
icon: Rocket,
|
||||
title: "Kaasaegsed tehnoloogiad",
|
||||
description: "Kasutame uusimaid tööriistu ja tehnoloogiaid"
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<Section background="orange">
|
||||
<Center>
|
||||
<div class="text-center max-w-4xl">
|
||||
<h1 class="text-5xl font-bold mb-6">Ettevõttele</h1>
|
||||
<p class="text-2xl leading-relaxed">
|
||||
Aitame sinu ideed ellu viia! Meie kogenud tudengid on valmis teie projekte realiseerima.
|
||||
</p>
|
||||
</div>
|
||||
</Center>
|
||||
</Section>
|
||||
|
||||
<!-- Services Section -->
|
||||
<Section>
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-4xl font-bold mb-4">Mida me pakume?</h2>
|
||||
<p class="text-xl text-gray-600">Laia valik IT-teenuseid teie ärivajaduste täitmiseks</p>
|
||||
</div>
|
||||
|
||||
<Grid columns={2} gap="var(--space-5)">
|
||||
{#each services as service}
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<svelte:component this={service.icon} size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">{service.title}</h3>
|
||||
<p class="text-gray-600">{service.description}</p>
|
||||
</Card>
|
||||
{/each}
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- Why Choose Us -->
|
||||
<Section background="neutral">
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-4xl font-bold mb-4">Miks meiega koostööd teha?</h2>
|
||||
</div>
|
||||
|
||||
<Grid columns={3} gap="var(--space-5)">
|
||||
{#each whyUs as item}
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<svelte:component this={item.icon} size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">{item.title}</h3>
|
||||
<p class="text-gray-600">{item.description}</p>
|
||||
</Card>
|
||||
{/each}
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- Process Section -->
|
||||
<Section>
|
||||
<Grid gap="var(--space-5)">
|
||||
<Card variant="glass">
|
||||
<h2 class="text-4xl font-bold mb-6">Kuidas töötame?</h2>
|
||||
<div class="space-y-6">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="text-3xl font-bold" style="color: var(--orange)">1.</div>
|
||||
<div>
|
||||
<strong class="text-lg">Esimene kohtumine</strong><br/>
|
||||
Arutame teie ideed, vajadusi ja eesmärke. Mõistame, mida soovite saavutada.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="text-3xl font-bold" style="color: var(--orange)">2.</div>
|
||||
<div>
|
||||
<strong class="text-lg">Planeerimine</strong><br/>
|
||||
Koostame projekti plaani, hinnapakkumise ja ajakava. Lepime kokku detailides.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="text-3xl font-bold" style="color: var(--orange)">3.</div>
|
||||
<div>
|
||||
<strong class="text-lg">Arendus</strong><br/>
|
||||
Meie meeskond töötab teie projekti kallal. Hoiame teid regulaarselt kursis.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="text-3xl font-bold" style="color: var(--orange)">4.</div>
|
||||
<div>
|
||||
<strong class="text-lg">Üleandmine</strong><br/>
|
||||
Anname valmis toote üle koos dokumentatsiooni ja juhendamisega.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="text-3xl font-bold" style="color: var(--orange)">5.</div>
|
||||
<div>
|
||||
<strong class="text-lg">Tugi</strong><br/>
|
||||
Pakume vajadusel jätkuvat tuge ja hooldust.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<h2 class="text-4xl font-bold mb-6">Millal meie sobime?</h2>
|
||||
<div class="space-y-4 text-lg">
|
||||
<p>
|
||||
<strong>Startup ja väikeettevõtted:</strong> Meie teenused on hinnaefektiivsed ja paindlikud,
|
||||
sobides hästi piiratud eelarvega projektidele.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Prototüüpide arendus:</strong> Vajate kiiresti töökorras prototüüpi?
|
||||
Meie agile meeskond suudab kiiresti teie idee ellu viia.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Lõputööd ja projektid:</strong> Teie projekt võib saada meie tudengite
|
||||
lõputöö teemaks, mis tagab motiveeritud ja pühendunud meeskonna.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Pikaajalised projektid:</strong> Pakume ka pikemaajalisi koostöövõimalusi
|
||||
keerulisemate süsteemide arendamiseks.
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- Portfolio Section -->
|
||||
<Section>
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-4xl font-bold mb-4">Meie tehtud tööd</h2>
|
||||
<p class="text-xl text-gray-600">Vaata, mida oleme varem loonud</p>
|
||||
</div>
|
||||
|
||||
<Grid columns={3} gap="var(--space-5)">
|
||||
{#each projects as project}
|
||||
<Card variant="animated-neutral">
|
||||
{#if project.photo}
|
||||
<div class="mb-4 overflow-hidden rounded-lg">
|
||||
<img
|
||||
src={`/assets/ourwork-images/optimised/${project.photo}`}
|
||||
alt={getLangText(project, 'title', $currentLang)}
|
||||
class="w-full h-48 object-cover hover:scale-105 transition-transform duration-300"
|
||||
on:error={(e) => {
|
||||
e.target.src = '/assets/ourwork-images/original/' + project.photo;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<h3 class="text-xl font-bold mb-2">{getLangText(project, 'title', $currentLang)}</h3>
|
||||
|
||||
{#if project.description}
|
||||
<p class="text-gray-600 text-sm mb-4">{getLangText(project, 'description', $currentLang)}</p>
|
||||
{/if}
|
||||
|
||||
{#if project.url}
|
||||
<a
|
||||
href={project.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center gap-2 text-orange-500 hover:text-orange-600 font-semibold"
|
||||
>
|
||||
Vaata projekti <ExternalLink size={16} />
|
||||
</a>
|
||||
{/if}
|
||||
</Card>
|
||||
{/each}
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- CTA Section -->
|
||||
<Section background="orange">
|
||||
<Center>
|
||||
<div class="text-center max-w-4xl text-white">
|
||||
<h2 class="text-4xl font-bold mb-6">Alustame koostööd?</h2>
|
||||
<p class="text-xl mb-8">
|
||||
Võta ühendust ja arutame, kuidas saame sinu ideed ellu viia!
|
||||
</p>
|
||||
<div class="flex flex-wrap gap-4 justify-center">
|
||||
<a
|
||||
href="mailto:lapikud@lapikud.ee"
|
||||
class="inline-flex items-center gap-2 px-8 py-3 bg-white text-orange-500 hover:bg-gray-100 font-semibold rounded-lg transition-colors"
|
||||
>
|
||||
Saada e-kiri <ArrowRight size={20} />
|
||||
</a>
|
||||
<a
|
||||
href="/contact"
|
||||
class="inline-flex items-center gap-2 px-8 py-3 bg-transparent border-2 border-white hover:bg-white hover:text-orange-500 font-semibold rounded-lg transition-colors"
|
||||
>
|
||||
Kontaktandmed
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</Center>
|
||||
</Section>
|
||||
|
||||
<style>
|
||||
.feature-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: rgba(255, 127, 0, 0.1);
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
210
src/routes/Student.svelte
Normal file
210
src/routes/Student.svelte
Normal file
@@ -0,0 +1,210 @@
|
||||
<script>
|
||||
import {
|
||||
Section,
|
||||
Grid,
|
||||
Card,
|
||||
Center,
|
||||
Container,
|
||||
} from "$components";
|
||||
import { onMount } from "svelte";
|
||||
import yaml from 'js-yaml';
|
||||
|
||||
import Users from "lucide-svelte/icons/users";
|
||||
import GraduationCap from "lucide-svelte/icons/graduation-cap";
|
||||
import Code from "lucide-svelte/icons/code";
|
||||
import Calendar from "lucide-svelte/icons/calendar";
|
||||
import Lightbulb from "lucide-svelte/icons/lightbulb";
|
||||
import Trophy from "lucide-svelte/icons/trophy";
|
||||
|
||||
let members = { junior: [], senior: [] };
|
||||
|
||||
onMount(async () => {
|
||||
const response = await fetch('/_data/members.yml');
|
||||
const yamlText = await response.text();
|
||||
members = yaml.load(yamlText);
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<Section background="orange">
|
||||
<Center>
|
||||
<div class="text-center max-w-4xl">
|
||||
<h1 class="text-5xl font-bold mb-6">Liitu Meiega!</h1>
|
||||
<p class="text-2xl leading-relaxed">
|
||||
Tule arenda oma oskuseid ja saa ägedaid sõpru! Omanda praktilist kogemust reaalsetest projektidest.
|
||||
</p>
|
||||
</div>
|
||||
</Center>
|
||||
</Section>
|
||||
|
||||
<!-- Benefits Section -->
|
||||
<Section>
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-4xl font-bold mb-4">Miks Lapikutega liituda?</h2>
|
||||
<p class="text-xl text-gray-600">Siin on mõned põhjused, miks meie kogukond on suurepärane koht arenguks</p>
|
||||
</div>
|
||||
|
||||
<Grid columns={3} gap="var(--space-5)">
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<Code size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">Praktilised projektid</h3>
|
||||
<p class="text-gray-600">
|
||||
Osale reaalsetel tarkvaraarenduse projektidel. Omanda kogemust, mida ei õpeta ühelgi kursusel.
|
||||
</p>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<Users size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">Tugev kogukond</h3>
|
||||
<p class="text-gray-600">
|
||||
Liitu sõbralike ja ambitsioonikate tudengitega. Leia oma meeskond ja loo püsivaid sõprussuhteid.
|
||||
</p>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<GraduationCap size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">Mentorlus</h3>
|
||||
<p class="text-gray-600">
|
||||
Saa juhendamist kogenud tudengitelt ja arendajatelt. Õpi parimate käest ja arene kiiremini.
|
||||
</p>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<Calendar size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">Üritused</h3>
|
||||
<p class="text-gray-600">
|
||||
Osale huvitavatel üritustel, hackathonidel ja koolitustel. Laienda oma silmaringi ja võrgustikku.
|
||||
</p>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<Lightbulb size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">Lõputööd</h3>
|
||||
<p class="text-gray-600">
|
||||
Meie projektidest kasvavad välja huvitavad lõputööd. Leia oma teema ja juhendaja meie seast.
|
||||
</p>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<div class="feature-icon mb-4" style="color: var(--orange)">
|
||||
<Trophy size={48} strokeWidth={1.5} />
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold mb-3">Töökogemus</h3>
|
||||
<p class="text-gray-600">
|
||||
Aktiivsed liikmed saavad võimaluse teenida oma esimest töökogemust ja palka meie projektides.
|
||||
</p>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- What You'll Do Section -->
|
||||
<Section background="neutral">
|
||||
<Grid gap="var(--space-5)">
|
||||
<Card variant="glass">
|
||||
<h2 class="text-4xl font-bold mb-4">Mida saad teha?</h2>
|
||||
<div class="space-y-4 text-lg">
|
||||
<p>
|
||||
<strong>Tarkvara arendus:</strong> Töötad reaalsetel projektidel kasutades kaasaegseid tehnoloogiaid.
|
||||
Õpid koodi kirjutamist meeskonnas, versioonihaldustööriistade kasutamist ja tarkvara kvaliteedi tagamist.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Helpdesk:</strong> Aita tudengeid ja õppejõude IT-probleemide lahendamisel.
|
||||
Arenda oma tehnilisi oskuseid ja õpi suhtlemist klientidega.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Projektijuhtimine:</strong> Võta vastutus projekti koordineerimise eest.
|
||||
Õpi planeerimist, meeskonna juhtimist ja suhtlemist klientidega.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Turundus ja disain:</strong> Aita meie projektide ja ürituste turundamisel.
|
||||
Loo sisu sotsiaalmeedias, disaini materjale ja jälgi tulemusi.
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<h2 class="text-4xl font-bold mb-4">Kuidas liituda?</h2>
|
||||
<div class="space-y-4 text-lg">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="text-3xl font-bold" style="color: var(--orange)">1.</div>
|
||||
<div>
|
||||
<strong>Võta ühendust</strong><br/>
|
||||
Kirjuta meile e-posti aadressil <a href="mailto:lapikud@lapikud.ee" class="text-orange-500 hover:underline">lapikud@lapikud.ee</a>
|
||||
või tule meie kontorisse Akadeemia tee 5.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="text-3xl font-bold" style="color: var(--orange)">2.</div>
|
||||
<div>
|
||||
<strong>Tutvumine</strong><br/>
|
||||
Kohtu meie meeskonnaga, tutvusta ennast ja räägi oma huvidest. Näitame sulle meie projekte ja võimalusi.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="text-3xl font-bold" style="color: var(--orange)">3.</div>
|
||||
<div>
|
||||
<strong>Alusta tööd</strong><br/>
|
||||
Leia endale sobiv projekt või meeskond ja hakka tegutsema! Meie mentorid aitavad sind iga sammu juures.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Section>
|
||||
|
||||
<!-- Members Section -->
|
||||
<Section>
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-4xl font-bold mb-4">Meie liikmed</h2>
|
||||
<p class="text-xl text-gray-600">Suurepärased inimesed, kes moodustavad meie kogukonna</p>
|
||||
</div>
|
||||
|
||||
{#if members.senior && members.senior.length > 0}
|
||||
<div class="mb-12">
|
||||
<h3 class="text-3xl font-bold mb-6 text-center">Senior liikmed</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">
|
||||
<p class="text-center font-medium">{member}</p>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if members.junior && members.junior.length > 0}
|
||||
<div>
|
||||
<h3 class="text-3xl font-bold mb-6 text-center">Junior liikmed</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">
|
||||
<p class="text-center font-medium">{member}</p>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</Section>
|
||||
|
||||
<style>
|
||||
.feature-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: rgba(255, 127, 0, 0.1);
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
@@ -2,7 +2,72 @@
|
||||
// examples: '/page', '/page/:id'
|
||||
|
||||
import Home from './Home.svelte'
|
||||
import Student from './Student.svelte'
|
||||
import Mentors from './Mentors.svelte'
|
||||
import Helpdesk from './Helpdesk.svelte'
|
||||
import OurWork from './OurWork.svelte'
|
||||
import AboutUs from './AboutUs.svelte'
|
||||
import Contact from './Contact.svelte'
|
||||
|
||||
// Route mapping for language switching
|
||||
export const routeMap = {
|
||||
// Home
|
||||
'/': { est: '/', en: '/' },
|
||||
|
||||
// Student/Tudengile
|
||||
'/tudengile': { est: '/tudengile', en: '/student' },
|
||||
'/student': { est: '/tudengile', en: '/student' },
|
||||
|
||||
// Mentors/Mentorid
|
||||
'/mentorid': { est: '/mentorid', en: '/mentors' },
|
||||
'/mentors': { est: '/mentorid', en: '/mentors' },
|
||||
|
||||
// Helpdesk
|
||||
'/helpdesk': { est: '/helpdesk', en: '/helpdesk' },
|
||||
|
||||
// OurWork/Ettevõttele
|
||||
'/ettevottele': { est: '/ettevottele', en: '/ourwork' },
|
||||
'/ourwork': { est: '/ettevottele', en: '/ourwork' },
|
||||
|
||||
// AboutUs/Lapikutest
|
||||
'/lapikutest': { est: '/lapikutest', en: '/aboutus' },
|
||||
'/aboutus': { est: '/lapikutest', en: '/aboutus' },
|
||||
|
||||
// Contact/Kontakt
|
||||
'/kontakt': { est: '/kontakt', en: '/contact' },
|
||||
'/contact': { est: '/kontakt', en: '/contact' },
|
||||
};
|
||||
|
||||
// Detect language from route
|
||||
export function getLanguageFromRoute(path) {
|
||||
const estRoutes = ['/tudengile', '/mentorid', '/ettevottele', '/lapikutest', '/kontakt'];
|
||||
const enRoutes = ['/student', '/mentors', '/ourwork', '/aboutus', '/contact'];
|
||||
|
||||
if (estRoutes.includes(path)) return 'est';
|
||||
if (enRoutes.includes(path)) return 'en';
|
||||
|
||||
// Default to Estonian
|
||||
return 'est';
|
||||
}
|
||||
|
||||
// Get translated route
|
||||
export function getTranslatedRoute(currentPath, targetLang) {
|
||||
const mapping = routeMap[currentPath];
|
||||
if (!mapping) return currentPath;
|
||||
return mapping[targetLang] || currentPath;
|
||||
}
|
||||
|
||||
export const routes = {
|
||||
'/': Home,
|
||||
'/tudengile': Student,
|
||||
'/student': Student,
|
||||
'/mentorid': Mentors,
|
||||
'/mentors': Mentors,
|
||||
'/helpdesk': Helpdesk,
|
||||
'/ettevottele': OurWork,
|
||||
'/ourwork': OurWork,
|
||||
'/lapikutest': AboutUs,
|
||||
'/aboutus': AboutUs,
|
||||
'/kontakt': Contact,
|
||||
'/contact': Contact,
|
||||
}
|
||||
Reference in New Issue
Block a user