mirror of
https://github.com/Lapikud/lapikud.github.io.git
synced 2026-08-08 21:29:14 +00:00
transfer
This commit is contained in:
@@ -1,4 +1,9 @@
|
|||||||
{
|
{
|
||||||
|
"intro": {
|
||||||
|
"prefix": "Our ",
|
||||||
|
"emphasis": "work.",
|
||||||
|
"subtitle": "A selection of projects our members have delivered, from websites to mobile apps."
|
||||||
|
},
|
||||||
"hero": {
|
"hero": {
|
||||||
"title": "For companies",
|
"title": "For companies",
|
||||||
"description": "We help bring your ideas to life. Our experienced students are ready to deliver your projects."
|
"description": "We help bring your ideas to life. Our experienced students are ready to deliver your projects."
|
||||||
@@ -89,9 +94,13 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"portfolio": {
|
"portfolio": {
|
||||||
"title": "Our work",
|
"label": "Our Work",
|
||||||
"subtitle": "See what we have built before",
|
"title": "Projects that speak for themselves.",
|
||||||
"projectLink": "View project"
|
"subtitle": "Every project has a story. Here is a selection of work our members have delivered over the years.",
|
||||||
|
"projectLink": "View project",
|
||||||
|
"featured": "Featured",
|
||||||
|
"placeholder": "No image",
|
||||||
|
"noDescription": "Description coming soon."
|
||||||
},
|
},
|
||||||
"cta": {
|
"cta": {
|
||||||
"title": "Shall we start working together?",
|
"title": "Shall we start working together?",
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
{
|
{
|
||||||
|
"intro": {
|
||||||
|
"prefix": "Meie tehtud ",
|
||||||
|
"emphasis": "tööd.",
|
||||||
|
"subtitle": "Valik projekte, mida meie liikmed on teostanud, veebilehtedest mobiilirakendusteni."
|
||||||
|
},
|
||||||
"hero": {
|
"hero": {
|
||||||
"title": "Ettevõttele",
|
"title": "Ettevõttele",
|
||||||
"description": "Aitame sinu ideed ellu viia! Meie kogenud tudengid on valmis teie projekte realiseerima."
|
"description": "Aitame sinu ideed ellu viia! Meie kogenud tudengid on valmis teie projekte realiseerima."
|
||||||
@@ -89,9 +94,13 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"portfolio": {
|
"portfolio": {
|
||||||
"title": "Meie tehtud tööd",
|
"label": "Tehtud tööd",
|
||||||
"subtitle": "Vaata, mida oleme varem loonud",
|
"title": "Projektid, mis räägivad enda eest.",
|
||||||
"projectLink": "Vaata projekti"
|
"subtitle": "Igal projektil on oma lugu. Siin on valik töödest, mida meie liikmed on aastate jooksul ellu viinud.",
|
||||||
|
"projectLink": "Vaata projekti",
|
||||||
|
"featured": "Esile tõstetud",
|
||||||
|
"placeholder": "Pilt puudub",
|
||||||
|
"noDescription": "Kirjeldus lisamisel."
|
||||||
},
|
},
|
||||||
"cta": {
|
"cta": {
|
||||||
"title": "Alustame koostööd?",
|
"title": "Alustame koostööd?",
|
||||||
|
|||||||
@@ -15,6 +15,6 @@
|
|||||||
|
|
||||||
<div class="safe-area-navbar">
|
<div class="safe-area-navbar">
|
||||||
<Section>
|
<Section>
|
||||||
{$text.placeholder || "In development..."}
|
<p>In development...</p>
|
||||||
</Section>
|
</Section>
|
||||||
</div>
|
</div>
|
||||||
@@ -2,321 +2,20 @@
|
|||||||
import {
|
import {
|
||||||
Section,
|
Section,
|
||||||
Grid,
|
Grid,
|
||||||
Card,
|
|
||||||
Center,
|
Center,
|
||||||
} from "$components";
|
} from "$components";
|
||||||
import { onDestroy } from "svelte";
|
import { onDestroy } from "svelte";
|
||||||
import { createPageTextStore } from "$lib";
|
import { createPageTextStore } from "$lib";
|
||||||
|
|
||||||
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 text = createPageTextStore("Contact");
|
const text = createPageTextStore("Contact");
|
||||||
|
|
||||||
$: contactMethods = [
|
|
||||||
{
|
|
||||||
icon: MapPin,
|
|
||||||
title: $text["methods"]?.addressTitle || "Aadress",
|
|
||||||
content: "Akadeemia tee 5, 12616 Tallinn",
|
|
||||||
subtitle: $text["methods"]?.addressSubtitle || "ICT-teaduskond, Raja 15 ruum 111",
|
|
||||||
link: "https://goo.gl/maps/..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: Mail,
|
|
||||||
title: $text["methods"]?.emailTitle || "E-post",
|
|
||||||
content: "lapikud@lapikud.ee",
|
|
||||||
link: "mailto:lapikud@lapikud.ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: Phone,
|
|
||||||
title: $text["methods"]?.phoneTitle || "Telefon",
|
|
||||||
content: "+372 58 160 799",
|
|
||||||
link: "tel:+37258160799"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: MessageCircle,
|
|
||||||
title: $text["methods"]?.messengerTitle || "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/"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
$: organizationInfo = [
|
|
||||||
{
|
|
||||||
icon: Building,
|
|
||||||
title: $text["organization"]?.registryTitle || "Registrikood",
|
|
||||||
content: "80167145"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: Building,
|
|
||||||
title: $text["organization"]?.bankTitle || "Pangakonto",
|
|
||||||
content: "EE812200221019551756",
|
|
||||||
subtitle: $text["organization"]?.bankSubtitle || "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(`${$text["form"]?.mailBody?.name || "Nimi"}: ${formData.name}\n${$text["form"]?.mailBody?.email || "E-post"}: ${formData.email}\n\n${$text["form"]?.mailBody?.message || "Sõnum"}:\n${formData.message}`)}`;
|
|
||||||
window.location.href = mailtoLink;
|
|
||||||
}
|
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
text.destroy();
|
text.destroy();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="safe-area-navbar">
|
<div class="safe-area-navbar">
|
||||||
<!-- Hero Section -->
|
|
||||||
<Section background="orange">
|
|
||||||
<Center>
|
|
||||||
<div class="text-center max-w-4xl">
|
|
||||||
<h1 class="text-5xl font-bold mb-6">{$text["hero"]?.title || "Võta ühendust"}</h1>
|
|
||||||
<p class="text-2xl leading-relaxed">
|
|
||||||
{$text["hero"]?.description || "Kas sul on küsimusi? Tahad liituda? Või soovid alustada koostööd? Võta julgelt ühendust!"}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</Center>
|
|
||||||
</Section>
|
|
||||||
|
|
||||||
<!-- Contact Methods -->
|
|
||||||
<Section>
|
<Section>
|
||||||
<div class="text-center mb-12">
|
<p>In development...</p>
|
||||||
<h2 class="text-4xl font-bold mb-4">{$text["methods"]?.title || "Kuidas meiega ühendust võtta?"}</h2>
|
|
||||||
<p class="text-xl text-gray-600">{$text["methods"]?.subtitle || "Vali endale sobiv viis"}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Grid columns={2} gap="gap-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">{$text["form"]?.title || "Saada meile sõnum"}</h2>
|
|
||||||
<p class="text-xl text-gray-600">{$text["form"]?.subtitle || "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">{$text["form"]?.nameLabel || "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={$text["form"]?.namePlaceholder || "Sinu nimi"}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="email" class="block text-sm font-semibold mb-2">{$text["form"]?.emailLabel || "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={$text["form"]?.emailPlaceholder || "sinu@email.ee"}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="subject" class="block text-sm font-semibold mb-2">{$text["form"]?.subjectLabel || "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={$text["form"]?.subjectPlaceholder || "Sõnumi teema"}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="message" class="block text-sm font-semibold mb-2">{$text["form"]?.messageLabel || "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={$text["form"]?.messagePlaceholder || "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"
|
|
||||||
>
|
|
||||||
{$text["form"]?.submit || "Saada sõnum"}
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</Section>
|
|
||||||
|
|
||||||
<!-- Office Hours & Location -->
|
|
||||||
<Section>
|
|
||||||
<Grid gap="gap-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">{$text["hours"]?.title || "Lahtiolekuajad"}</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-3 text-lg">
|
|
||||||
<div class="flex justify-between">
|
|
||||||
<span class="font-semibold">{$text["hours"]?.weekdays || "Esmaspäev - Reede:"}</span>
|
|
||||||
<span>{$text["hours"]?.weekdaysTime || "10:00 - 16:00"}</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex justify-between">
|
|
||||||
<span class="font-semibold">{$text["hours"]?.weekend || "Laupäev - Pühapäev:"}</span>
|
|
||||||
<span>{$text["hours"]?.weekendTime || "Suletud"}</span>
|
|
||||||
</div>
|
|
||||||
<p class="text-sm text-gray-600 mt-4">
|
|
||||||
{$text["hours"]?.note || "* 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">{$text["location"]?.title || "Kuidas meid leida?"}</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-3 text-lg">
|
|
||||||
<p><strong>{$text["location"]?.addressLabel || "Aadress:"}</strong> {$text["location"]?.address || "Akadeemia tee 5, 12616 Tallinn"}</p>
|
|
||||||
<p><strong>{$text["location"]?.buildingLabel || "Hoone:"}</strong> {$text["location"]?.building || "ICT-teaduskond (Raja 15)"}</p>
|
|
||||||
<p><strong>{$text["location"]?.roomLabel || "Ruum:"}</strong> {$text["location"]?.room || "111"}</p>
|
|
||||||
<p class="text-sm text-gray-600 mt-4">
|
|
||||||
{$text["location"]?.note || "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="gap-5">
|
|
||||||
<Card variant="glass">
|
|
||||||
<h2 class="text-3xl font-bold mb-6 text-center">{$text["social"]?.title || "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">{$text["organization"]?.title || "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>
|
</Section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|||||||
@@ -1,189 +1,174 @@
|
|||||||
<script>
|
<script>
|
||||||
import {
|
import { Section, Grid, Card, Button } from "$components";
|
||||||
Section,
|
|
||||||
Grid,
|
|
||||||
Card,
|
|
||||||
Center,
|
|
||||||
} from "$components";
|
|
||||||
import { onMount, onDestroy } from "svelte";
|
import { onMount, onDestroy } from "svelte";
|
||||||
import yaml from 'js-yaml';
|
import yaml from "js-yaml";
|
||||||
import { currentLang, getLangText, createPageTextStore } from "$lib";
|
import { currentLang, getLangText, createPageTextStore } 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";
|
import ExternalLink from "lucide-svelte/icons/external-link";
|
||||||
|
|
||||||
let projects = [];
|
let projects = [];
|
||||||
const text = createPageTextStore("OurWork");
|
const text = createPageTextStore("OurWork");
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
const response = await fetch('/_data/ourwork.yml');
|
const response = await fetch("/_data/ourwork.yml");
|
||||||
const yamlText = await response.text();
|
const yamlText = await response.text();
|
||||||
projects = yaml.load(yamlText).filter(p => p.title);
|
const parsed = yaml.load(yamlText) || [];
|
||||||
|
projects = parsed.filter((p) => p?.title);
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
text.destroy();
|
text.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
$: services = [
|
$: featuredProject = projects[0] || null;
|
||||||
{
|
$: regularProjects = projects.slice(1);
|
||||||
icon: Globe,
|
|
||||||
title: $text["services"]?.items?.[0]?.title || "Veebilahendused",
|
|
||||||
description: $text["services"]?.items?.[0]?.description || "Kaasaegsed ja responsiivsed veebilehed, mis toimivad igal seadmel"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: Smartphone,
|
|
||||||
title: $text["services"]?.items?.[1]?.title || "Mobiilirakendused",
|
|
||||||
description: $text["services"]?.items?.[1]?.description || "iOS ja Android rakendused kasutajasõbralike liidestega"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: Code,
|
|
||||||
title: $text["services"]?.items?.[2]?.title || "Tarkvara arendus",
|
|
||||||
description: $text["services"]?.items?.[2]?.description || "Kohandatud tarkvaralahendused teie ärivajadusteks"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: Briefcase,
|
|
||||||
title: $text["services"]?.items?.[3]?.title || "Konsultatsioon",
|
|
||||||
description: $text["services"]?.items?.[3]?.description || "IT-nõustamine ja projekti planeerimine"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
$: whyUs = [
|
function projectTitle(project) {
|
||||||
{
|
return getLangText(project, "title", $currentLang);
|
||||||
icon: Users,
|
}
|
||||||
title: $text["whyUs"]?.items?.[0]?.title || "Motiveeritud meeskond",
|
|
||||||
description: $text["whyUs"]?.items?.[0]?.description || "Meie tudengid on andekad, õhevil ja tahavad tõestada oma oskuseid"
|
function projectDescription(project) {
|
||||||
},
|
return getLangText(project, "description", $currentLang);
|
||||||
{
|
}
|
||||||
icon: Target,
|
|
||||||
title: $text["whyUs"]?.items?.[1]?.title || "Kvaliteetne tulemus",
|
function projectImage(project) {
|
||||||
description: $text["whyUs"]?.items?.[1]?.description || "Võtame iga projekti tõsiselt ja pingutame parima tulemuse nimel"
|
return project?.photo
|
||||||
},
|
? `/assets/ourwork-images/optimised/${project.photo}`
|
||||||
{
|
: "";
|
||||||
icon: Rocket,
|
}
|
||||||
title: $text["whyUs"]?.items?.[2]?.title || "Kaasaegsed tehnoloogiad",
|
|
||||||
description: $text["whyUs"]?.items?.[2]?.description || "Kasutame uusimaid tööriistu ja tehnoloogiaid"
|
function handleImageError(event, photo) {
|
||||||
|
event.currentTarget.src = `/assets/ourwork-images/original/${photo}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function openCtaEmail() {
|
||||||
|
window.location.href = "mailto:lapikud@lapikud.ee";
|
||||||
|
}
|
||||||
|
|
||||||
|
function openCtaContact() {
|
||||||
|
window.location.href = "/contact";
|
||||||
}
|
}
|
||||||
];
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="safe-area-navbar">
|
<div class="safe-area-navbar">
|
||||||
<!-- Hero Section -->
|
|
||||||
<Section background="orange">
|
<!-- Hero Section -->
|
||||||
<Center>
|
<Section
|
||||||
<div class="text-center max-w-4xl">
|
padding="none"
|
||||||
<h1 class="text-5xl font-bold mb-6">{$text["hero"]?.title || "Ettevõttele"}</h1>
|
bg="bg-gray-900"
|
||||||
<p class="text-2xl leading-relaxed">
|
class="overflow-hidden"
|
||||||
{$text["hero"]?.description || "Aitame sinu ideed ellu viia! Meie kogenud tudengid on valmis teie projekte realiseerima."}
|
contentClass="relative z-10 py-[clamp(3.5rem,8vw,5rem)]"
|
||||||
|
>
|
||||||
|
<div class="relative z-10">
|
||||||
|
<h1 class="max-w-[20ch] text-[clamp(2.6rem,5.5vw,4.8rem)] leading-none font-bold tracking-[-0.03em] text-white">
|
||||||
|
{$text["intro"]?.prefix || "Meie tehtud "}
|
||||||
|
<br />
|
||||||
|
<span class="text-orange-500">{$text["intro"]?.emphasis || "tööd."}</span>
|
||||||
|
</h1>
|
||||||
|
<p class="mt-5 max-w-105 text-[0.95rem] leading-[1.7] text-white/45">
|
||||||
|
{$text["intro"]?.subtitle || "Valik projekte, mida meie liikmed on teostanud, veebilehtedest mobiilirakendusteni."}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Center>
|
</Section>
|
||||||
</Section>
|
|
||||||
|
|
||||||
<!-- Services Section -->
|
<!-- CTA Section -->
|
||||||
<Section>
|
<Section
|
||||||
<div class="text-center mb-12">
|
padding="none"
|
||||||
<h2 class="text-4xl font-bold mb-4">{$text["services"]?.title || "Mida me pakume?"}</h2>
|
bg="bg-orange-500"
|
||||||
<p class="text-xl text-gray-600">{$text["services"]?.subtitle || "Laia valik IT-teenuseid teie ärivajaduste täitmiseks"}</p>
|
contentClass="py-[clamp(2.3rem,5vw,3.25rem)]"
|
||||||
</div>
|
>
|
||||||
|
<div class="flex flex-col items-start justify-between gap-6 lg:flex-row lg:items-center lg:gap-10">
|
||||||
<Grid columns={2} gap="gap-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">{$text["whyUs"]?.title || "Miks meiega koostööd teha?"}</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Grid columns={3} gap="gap-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="gap-5">
|
|
||||||
<Card variant="glass">
|
|
||||||
<h2 class="text-4xl font-bold mb-6">{$text["process"]?.title || "Kuidas töötame?"}</h2>
|
|
||||||
<div class="space-y-6">
|
|
||||||
{#each $text["process"]?.steps || [] as step, index}
|
|
||||||
<div class="flex items-start gap-4">
|
|
||||||
<div class="text-3xl font-bold" style="color: var(--orange)">{index + 1}.</div>
|
|
||||||
<div>
|
<div>
|
||||||
<strong class="text-lg">{step.title}</strong><br/>
|
<h2 class="mb-2 text-[clamp(1.4rem,2.5vw,2rem)] leading-[1.1] font-bold tracking-[-0.02em] text-gray-900">
|
||||||
{step.description}
|
{$text["cta"]?.title || "Alustame koostööd?"}
|
||||||
</div>
|
</h2>
|
||||||
</div>
|
<p class="max-w-95 text-[0.88rem] leading-[1.6] text-gray-900/70">
|
||||||
{/each}
|
{$text["cta"]?.description || "Võta ühendust ja arutame, kuidas saame sinu ideed ellu viia!"}
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card variant="glass">
|
|
||||||
<h2 class="text-4xl font-bold mb-6">{$text["fit"]?.title || "Millal meie sobime?"}</h2>
|
|
||||||
<div class="space-y-4 text-lg">
|
|
||||||
{#each $text["fit"]?.items || [] as item}
|
|
||||||
<p>
|
|
||||||
<strong>{item.title}</strong> {item.description}
|
|
||||||
</p>
|
</p>
|
||||||
{/each}
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap items-center gap-3">
|
||||||
|
<Button
|
||||||
|
onClick={openCtaEmail}
|
||||||
|
class="gap-2 rounded-none! border-gray-900! bg-gray-900 px-5.5 py-3 text-[0.83rem] font-semibold text-white transition-colors hover:border-gray-800 hover:bg-gray-800"
|
||||||
|
>
|
||||||
|
{$text["cta"]?.emailButton || "Saada e-kiri"} <span aria-hidden="true">→</span>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={openCtaContact}
|
||||||
|
class="rounded-none! border-gray-900/35! bg-transparent px-5.5 py-3 text-[0.83rem] font-semibold text-gray-900 transition-colors hover:border-gray-900 hover:bg-gray-900/6"
|
||||||
|
>
|
||||||
|
{$text["cta"]?.contactButton || "Kontaktandmed"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
|
|
||||||
|
<Section padding="large">
|
||||||
|
<div class="mb-12">
|
||||||
|
<p class="mb-3 text-[0.72rem] font-bold uppercase tracking-[0.12em] text-orange-500">{$text["portfolio"]?.label || "Tehtud tööd"}</p>
|
||||||
|
<h1 class="m-0 max-w-[20ch] text-[clamp(1.9rem,4vw,3.15rem)] leading-[1.08] tracking-[-0.03em]">{$text["portfolio"]?.title || "Projektid, mis räägivad enda eest."}</h1>
|
||||||
|
<p class="mt-4 max-w-[62ch] leading-[1.65] text-gray-900">
|
||||||
|
{$text["portfolio"]?.subtitle || "Igal projektil on oma lugu. Siin on valik töödest, mida meie liikmed on aastate jooksul ellu viinud."}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if featuredProject}
|
||||||
|
<Card class="mb-5! grid! overflow-hidden! rounded-none! border-0! bg-white! p-0! ring-1 ring-gray-200 md:grid-cols-[1.25fr_1fr]!" variant="default">
|
||||||
|
<div class="min-h-[220px] overflow-hidden bg-gray-100/70 p-2 md:min-h-[280px]">
|
||||||
|
{#if featuredProject.photo}
|
||||||
|
<img
|
||||||
|
src={projectImage(featuredProject)}
|
||||||
|
alt={projectTitle(featuredProject)}
|
||||||
|
class="block h-full w-full border border-gray-200 bg-white object-contain object-center shadow-[0_1px_2px_rgba(13,13,13,0.05)]"
|
||||||
|
on:error={(event) => handleImageError(event, featuredProject.photo)}
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
|
<div class="grid h-full min-h-[180px] w-full place-items-center text-[0.85rem] text-gray-900">{$text["portfolio"]?.placeholder || "Pilt puudub"}</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col justify-center gap-2 p-[clamp(1.5rem,3vw,2.5rem)]">
|
||||||
|
<h2 class="m-0 text-[clamp(1.45rem,2.7vw,2rem)] leading-[1.2] tracking-[-0.02em]">{projectTitle(featuredProject)}</h2>
|
||||||
|
{#if projectDescription(featuredProject)}
|
||||||
|
<p class="m-0 text-[0.9rem] leading-[1.6] text-gray-900">{projectDescription(featuredProject)}</p>
|
||||||
|
{/if}
|
||||||
|
{#if featuredProject.url}
|
||||||
|
<a
|
||||||
|
href={featuredProject.url}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="mt-0.5 inline-flex w-fit items-center gap-1.5 font-semibold text-orange-500 hover:underline"
|
||||||
|
>
|
||||||
|
{$text["portfolio"]?.projectLink || "Vaata projekti"}
|
||||||
|
<ExternalLink size={16} />
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
|
||||||
</Section>
|
|
||||||
|
|
||||||
<!-- Portfolio Section -->
|
|
||||||
<Section>
|
|
||||||
<div class="text-center mb-12">
|
|
||||||
<h2 class="text-4xl font-bold mb-4">{$text["portfolio"]?.title || "Meie tehtud tööd"}</h2>
|
|
||||||
<p class="text-xl text-gray-600">{$text["portfolio"]?.subtitle || "Vaata, mida oleme varem loonud"}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Grid columns={3} gap="gap-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}
|
{/if}
|
||||||
|
<div class="ourwork-grid">
|
||||||
|
{#each regularProjects as project}
|
||||||
|
<Card variant="default" class="ourwork-grid-card rounded-none! border-0! bg-white! p-0!">
|
||||||
|
<div class="aspect-16/10 overflow-hidden bg-gray-100/70 p-2">
|
||||||
|
{#if project.photo}
|
||||||
|
<img
|
||||||
|
src={projectImage(project)}
|
||||||
|
alt={projectTitle(project)}
|
||||||
|
class="block h-full w-full border border-gray-200 bg-white object-contain object-center shadow-[0_1px_2px_rgba(13,13,13,0.05)]"
|
||||||
|
on:error={(event) => handleImageError(event, project.photo)}
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
|
<div class="grid h-full min-h-[180px] w-full place-items-center text-[0.85rem] text-gray-900">{$text["portfolio"]?.placeholder || "Pilt puudub"}</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3 class="text-xl font-bold mb-2">{getLangText(project, 'title', $currentLang)}</h3>
|
<div class="ourwork-card-content flex h-full flex-1 flex-col gap-2 p-5">
|
||||||
|
<h3 class="ourwork-card-title m-0 text-base leading-[1.2] tracking-[-0.02em]">{projectTitle(project)}</h3>
|
||||||
{#if project.description}
|
{#if projectDescription(project)}
|
||||||
<p class="text-gray-600 text-sm mb-4">{getLangText(project, 'description', $currentLang)}</p>
|
<p class="ourwork-card-description m-0 text-[0.9rem] leading-[1.6] text-gray-900">{projectDescription(project)}</p>
|
||||||
|
{:else}
|
||||||
|
<p class="ourwork-card-description m-0 text-[0.9rem] leading-[1.6] text-gray-900 italic">{$text["portfolio"]?.noDescription || "Kirjeldus lisamisel."}</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if project.url}
|
{#if project.url}
|
||||||
@@ -191,52 +176,66 @@
|
|||||||
href={project.url}
|
href={project.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="inline-flex items-center gap-2 text-orange-500 hover:text-orange-600 font-semibold"
|
class="mt-auto inline-flex w-fit items-center gap-1.5 pt-1 font-semibold text-orange-500 hover:underline"
|
||||||
>
|
>
|
||||||
{$text["portfolio"]?.projectLink || "Vaata projekti"} <ExternalLink size={16} />
|
{$text["portfolio"]?.projectLink || "Vaata projekti"}
|
||||||
|
<ExternalLink size={16} />
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
{/each}
|
{/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">{$text["cta"]?.title || "Alustame koostööd?"}</h2>
|
|
||||||
<p class="text-xl mb-8">
|
|
||||||
{$text["cta"]?.description || "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"
|
|
||||||
>
|
|
||||||
{$text["cta"]?.emailButton || "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"
|
|
||||||
>
|
|
||||||
{$text["cta"]?.contactButton || "Kontaktandmed"}
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Section>
|
||||||
</Center>
|
|
||||||
</Section>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.feature-icon {
|
.ourwork-grid {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-wrap: wrap;
|
||||||
|
gap: 1px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 80px;
|
}
|
||||||
height: 80px;
|
|
||||||
background: rgba(255, 127, 0, 0.1);
|
.ourwork-grid :global(.ourwork-grid-card) {
|
||||||
border-radius: 50%;
|
display: flex;
|
||||||
margin: 0 auto;
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ourwork-card-content {
|
||||||
|
min-height: 10.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ourwork-card-title {
|
||||||
|
min-height: calc(1.2em * 2);
|
||||||
|
display: -webkit-box;
|
||||||
|
line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ourwork-card-description {
|
||||||
|
min-height: calc(1.6em * 3);
|
||||||
|
display: -webkit-box;
|
||||||
|
line-clamp: 3;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.ourwork-grid :global(.ourwork-grid-card) {
|
||||||
|
width: calc((100% - 1px) / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
.ourwork-grid :global(.ourwork-grid-card) {
|
||||||
|
width: calc((100% - 2px) / 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -30,6 +30,10 @@
|
|||||||
document.getElementById("liitu")?.scrollIntoView({ behavior: "smooth", block: "start" });
|
document.getElementById("liitu")?.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const scrollToUnderHero = () => {
|
||||||
|
document.getElementById("tiimid")?.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||||
|
};
|
||||||
|
|
||||||
const openJoinForm = () => {
|
const openJoinForm = () => {
|
||||||
window.open(joinFormUrl, "_blank", "noopener,noreferrer");
|
window.open(joinFormUrl, "_blank", "noopener,noreferrer");
|
||||||
};
|
};
|
||||||
@@ -62,7 +66,7 @@
|
|||||||
<Button onClick={scrollToJoin} class="border-transparent bg-orange-500 px-8 py-3 text-sm font-semibold text-white hover:opacity-90">
|
<Button onClick={scrollToJoin} class="border-transparent bg-orange-500 px-8 py-3 text-sm font-semibold text-white hover:opacity-90">
|
||||||
{$text["hero"]?.cta || ""}
|
{$text["hero"]?.cta || ""}
|
||||||
</Button>
|
</Button>
|
||||||
<span class="text-sm text-white/40">{$text["hero"]?.aside || ""}</span>
|
<a href="#tiimid" on:click|preventDefault={scrollToUnderHero} class="text-sm text-white/40">{$text["hero"]?.aside || ""}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
21
src/routes/Workshops.svelte
Normal file
21
src/routes/Workshops.svelte
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<script>
|
||||||
|
import {
|
||||||
|
Section,
|
||||||
|
Grid,
|
||||||
|
Center,
|
||||||
|
} from "$components";
|
||||||
|
import { onDestroy } from "svelte";
|
||||||
|
import { createPageTextStore } from "$lib";
|
||||||
|
|
||||||
|
const text = createPageTextStore("Workshops");
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
text.destroy();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="safe-area-navbar">
|
||||||
|
<Section>
|
||||||
|
<p>In development...</p>
|
||||||
|
</Section>
|
||||||
|
</div>
|
||||||
@@ -11,6 +11,7 @@ import Contact from './Contact.svelte'
|
|||||||
import Managment from './Managment.svelte'
|
import Managment from './Managment.svelte'
|
||||||
import Striim from './Striim.svelte'
|
import Striim from './Striim.svelte'
|
||||||
import Calendar from './Calendar.svelte'
|
import Calendar from './Calendar.svelte'
|
||||||
|
import Workshops from './Workshops.svelte';
|
||||||
|
|
||||||
// Route mapping for language switching
|
// Route mapping for language switching
|
||||||
export const routeMap = {
|
export const routeMap = {
|
||||||
@@ -104,8 +105,8 @@ export const routes = {
|
|||||||
'/contact': Contact,
|
'/contact': Contact,
|
||||||
'/juhatus': Managment,
|
'/juhatus': Managment,
|
||||||
'/management': Managment,
|
'/management': Managment,
|
||||||
'/koolitused': Home, // TODO
|
'/koolitused': Workshops,
|
||||||
'/workshops': Home, // TODO
|
'/workshops': Workshops,
|
||||||
'/striim': Striim,
|
'/striim': Striim,
|
||||||
'/kalender': Calendar,
|
'/kalender': Calendar,
|
||||||
'/calendar': Calendar,
|
'/calendar': Calendar,
|
||||||
|
|||||||
Reference in New Issue
Block a user