mirror of
https://github.com/Lapikud/lapikud.github.io.git
synced 2026-08-08 21:29:14 +00:00
initial stuff
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>lapikud.github.io</title>
|
<title>Lapikud</title>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
var redirect = sessionStorage.redirect;
|
var redirect = sessionStorage.redirect;
|
||||||
|
|||||||
30
package-lock.json
generated
30
package-lock.json
generated
@@ -7,6 +7,9 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "lapikud.github.io",
|
"name": "lapikud.github.io",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"lucide-svelte": "^0.554.0"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
||||||
"svelte": "^5.43.8",
|
"svelte": "^5.43.8",
|
||||||
@@ -51,7 +54,6 @@
|
|||||||
"version": "0.3.13",
|
"version": "0.3.13",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||||
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
|
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/sourcemap-codec": "^1.5.0",
|
"@jridgewell/sourcemap-codec": "^1.5.0",
|
||||||
@@ -62,7 +64,6 @@
|
|||||||
"version": "2.3.5",
|
"version": "2.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
|
||||||
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
|
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/gen-mapping": "^0.3.5",
|
"@jridgewell/gen-mapping": "^0.3.5",
|
||||||
@@ -73,7 +74,6 @@
|
|||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
@@ -83,14 +83,12 @@
|
|||||||
"version": "1.5.5",
|
"version": "1.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/trace-mapping": {
|
"node_modules/@jridgewell/trace-mapping": {
|
||||||
"version": "0.3.31",
|
"version": "0.3.31",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
|
||||||
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
|
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/resolve-uri": "^3.1.0",
|
"@jridgewell/resolve-uri": "^3.1.0",
|
||||||
@@ -379,7 +377,6 @@
|
|||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.7.tgz",
|
||||||
"integrity": "sha512-znp1A/Y1Jj4l/Zy7PX5DZKBE0ZNY+5QBngiE21NJkfSTyzzC5iKNWOtwFXKtIrn7MXEFBck4jD95iBNkGjK92Q==",
|
"integrity": "sha512-znp1A/Y1Jj4l/Zy7PX5DZKBE0ZNY+5QBngiE21NJkfSTyzzC5iKNWOtwFXKtIrn7MXEFBck4jD95iBNkGjK92Q==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"acorn": "^8.9.0"
|
"acorn": "^8.9.0"
|
||||||
@@ -440,14 +437,12 @@
|
|||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
||||||
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
|
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.15.0",
|
"version": "8.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -461,7 +456,6 @@
|
|||||||
"version": "5.3.2",
|
"version": "5.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
|
||||||
"integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
|
"integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -471,7 +465,6 @@
|
|||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
|
||||||
"integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
|
"integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -481,7 +474,6 @@
|
|||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||||
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
|
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
@@ -529,14 +521,12 @@
|
|||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz",
|
||||||
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
|
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/esrap": {
|
"node_modules/esrap": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.3.tgz",
|
||||||
"integrity": "sha512-T/Dhhv/QH+yYmiaLz9SA3PW+YyenlnRKDNdtlYJrSOBmNsH4nvPux+mTwx7p+wAedlJrGoZtXNI0a0MjQ2QkVg==",
|
"integrity": "sha512-T/Dhhv/QH+yYmiaLz9SA3PW+YyenlnRKDNdtlYJrSOBmNsH4nvPux+mTwx7p+wAedlJrGoZtXNI0a0MjQ2QkVg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||||
@@ -579,7 +569,6 @@
|
|||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
|
||||||
"integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
|
"integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "^1.0.6"
|
"@types/estree": "^1.0.6"
|
||||||
@@ -850,14 +839,21 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
|
||||||
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
|
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/lucide-svelte": {
|
||||||
|
"version": "0.554.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lucide-svelte/-/lucide-svelte-0.554.0.tgz",
|
||||||
|
"integrity": "sha512-LLcpHi3SuKup0nVD1kKqo8FDZnjXJp48uST26GGh8Jcyrxqk5gmgpnvKmHsHox674UL3cPS1DCul/wFL7ybGqg==",
|
||||||
|
"license": "ISC",
|
||||||
|
"peerDependencies": {
|
||||||
|
"svelte": "^3 || ^4 || ^5.0.0-next.42"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
"version": "0.30.21",
|
"version": "0.30.21",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
|
||||||
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
|
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/sourcemap-codec": "^1.5.5"
|
"@jridgewell/sourcemap-codec": "^1.5.5"
|
||||||
@@ -986,7 +982,6 @@
|
|||||||
"version": "5.43.13",
|
"version": "5.43.13",
|
||||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.43.13.tgz",
|
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.43.13.tgz",
|
||||||
"integrity": "sha512-K1QJbpc71OHs3egN/ZHN+nsH/eE/eJQUbtlTAAXVejOOjsFx9hM96fCX5fwPQIYclJfVS8D96RDFA76nZsrJ3w==",
|
"integrity": "sha512-K1QJbpc71OHs3egN/ZHN+nsH/eE/eJQUbtlTAAXVejOOjsFx9hM96fCX5fwPQIYclJfVS8D96RDFA76nZsrJ3w==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1136,7 +1131,6 @@
|
|||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
|
||||||
"integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==",
|
"integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,5 +15,8 @@
|
|||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"vite": "npm:rolldown-vite@7.2.5"
|
"vite": "npm:rolldown-vite@7.2.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"lucide-svelte": "^0.554.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
public/locales/en.json
Normal file
28
public/locales/en.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"nav": {
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"content": {},
|
||||||
|
"footer": {
|
||||||
|
"address": "Address: ",
|
||||||
|
"mail": "E-mail: ",
|
||||||
|
"messenger": "Messenger: ",
|
||||||
|
"reg": "Reg. code: ",
|
||||||
|
"toast": "Our socials! Follow us for updates and news."
|
||||||
|
}
|
||||||
|
}
|
||||||
28
public/locales/est.json
Normal file
28
public/locales/est.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"nav": {
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"content": {},
|
||||||
|
"footer": {
|
||||||
|
"address": "Aadress: ",
|
||||||
|
"mail": "E-post: ",
|
||||||
|
"messenger": "Messenger: ",
|
||||||
|
"reg": "Reg. kood: ",
|
||||||
|
"toast": "Meie sotsiaalid! Jälgi meid uuenduste ja uudiste saamiseks."
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import Router from "./lib/Router.svelte";
|
import { Router, text } from "$lib";
|
||||||
import { routes } from "./routes/index.js";
|
import { routes } from "./routes/index.js";
|
||||||
import { theme, toggle } from "./lib/theme.js";
|
|
||||||
import Navbar from "./layout/Navbar.svelte";
|
import Navbar from "./layout/Navbar.svelte";
|
||||||
import Footer from "./layout/Footer.svelte";
|
import Footer from "./layout/Footer.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Navbar />
|
{#if $text.nav}
|
||||||
|
<!--<Navbar /> Ära vaata seda faili!! -->
|
||||||
<Router {routes} />
|
<Router {routes} />
|
||||||
<Footer />
|
<Footer />
|
||||||
|
{/if}
|
||||||
<!-- use $theme to show current state -->
|
|
||||||
<button
|
|
||||||
onclick={toggle}
|
|
||||||
style="position:fixed;right:1rem;bottom:1rem"
|
|
||||||
aria-label="Toggle theme"
|
|
||||||
>
|
|
||||||
{#if $theme === "dark"}☀️{:else}🌙{/if}
|
|
||||||
</button>
|
|
||||||
|
|||||||
@@ -12,12 +12,37 @@ Running `npm run dev` starts a local development server with hot reloading (so y
|
|||||||
>
|
>
|
||||||
> DO NOT TOUCH unless you know what you're doing! If you want to tinker, then do. When it breaks it just doesn't load any pages
|
> DO NOT TOUCH unless you know what you're doing! If you want to tinker, then do. When it breaks it just doesn't load any pages
|
||||||
|
|
||||||
|
## Internationalization (i18n)
|
||||||
|
|
||||||
|
This project uses a simple custom i18n solution defined in `src/lib/i18n.js`.
|
||||||
|
|
||||||
|
Import it with `$lib` alias as:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { currentLang, text, switchLang } from "$lib";
|
||||||
|
```
|
||||||
|
|
||||||
|
text contains a Svelte store that holds the current translations. To use it in a Svelte component, use the `$` prefix to auto-subscribe to the store:
|
||||||
|
|
||||||
|
```js
|
||||||
|
<p>{$text.key}</p> //replace the key with the translation key example: "nav.about"
|
||||||
|
```
|
||||||
|
|
||||||
## Styling
|
## Styling
|
||||||
|
|
||||||
Look at `src/app.css` for global styles and CSS variables. Each Svelte component can also have its own styles scoped to that component
|
Look at `src/app.css` for global styles and CSS variables. Each Svelte component can also have its own styles scoped to that component
|
||||||
|
|
||||||
Variables are defined in `:root`
|
Variables are defined in `:root`
|
||||||
|
|
||||||
|
we only have 3 colors in out palette + 2 variants:
|
||||||
|
|
||||||
|
- `--orange`
|
||||||
|
- `--black`
|
||||||
|
- `--white`
|
||||||
|
|
||||||
|
- `--off-white`
|
||||||
|
- `--off-black`
|
||||||
|
|
||||||
Add new ones only if they seem universal enough to be used in multiple places, don't add stuff like `--space-100: -888px` noone else will ever use that, if you really need it just add it to the component's own style block
|
Add new ones only if they seem universal enough to be used in multiple places, don't add stuff like `--space-100: -888px` noone else will ever use that, if you really need it just add it to the component's own style block
|
||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
@@ -39,3 +64,14 @@ There are also helper classes for responsive design:
|
|||||||
These classes use media queries defined in `src/app.css` based on common breakpoints.
|
These classes use media queries defined in `src/app.css` based on common breakpoints.
|
||||||
|
|
||||||
also things like `.stack`, `.inline`, `.grid`. Go look at `src/app.css` for what they do.
|
also things like `.stack`, `.inline`, `.grid`. Go look at `src/app.css` for what they do.
|
||||||
|
|
||||||
|
## Routing
|
||||||
|
|
||||||
|
Routing is handled by the custom router in `src/lib/Router.svelte` and `src/lib/router/router.js`.
|
||||||
|
To add new routes, edit `src/routes/index.js` and add your new route there.
|
||||||
|
|
||||||
|
Import router functions as:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { navigate, goBack, reload, getPath, getQuery } from "$lib"; // only import what you need
|
||||||
|
```
|
||||||
|
|||||||
41
src/app.css
41
src/app.css
@@ -3,14 +3,11 @@
|
|||||||
/* Design tokens & theme variables (light defaults) */
|
/* Design tokens & theme variables (light defaults) */
|
||||||
:root {
|
:root {
|
||||||
/* color tokens (light defaults) */
|
/* color tokens (light defaults) */
|
||||||
--color-bg: #ffffff;
|
--orange: #f0941d;
|
||||||
--color-surface: #f7f8fb;
|
--black: #000000;
|
||||||
--color-text: #0f1720;
|
--off-black: #0d0d0d;
|
||||||
--color-muted: #6b7280;
|
--white: #ffffff;
|
||||||
--color-primary: #4f46e5;
|
--off-white: #fffdfa;
|
||||||
--color-primary-600: #4338ca;
|
|
||||||
--color-border: rgba(15, 23, 32, 0.08);
|
|
||||||
--color-danger: #ef4444;
|
|
||||||
|
|
||||||
/* layout tokens */
|
/* layout tokens */
|
||||||
--site-padding: clamp(1rem, 2vw, 2rem); /* horizontal page padding */
|
--site-padding: clamp(1rem, 2vw, 2rem); /* horizontal page padding */
|
||||||
@@ -31,7 +28,8 @@
|
|||||||
--radius-sm: 6px;
|
--radius-sm: 6px;
|
||||||
--radius-md: 10px;
|
--radius-md: 10px;
|
||||||
--radius-lg: 14px;
|
--radius-lg: 14px;
|
||||||
--shadow-1: 0 1px 2px rgba(2, 6, 23, 0.06), 0 1px 3px rgba(2, 6, 23, 0.04);
|
--shadow-1: 0 1px 2px rgba(240, 148, 29, 0.2),
|
||||||
|
0 1px 3px rgba(240, 148, 29, 0.12);
|
||||||
|
|
||||||
/* breakpoints */
|
/* breakpoints */
|
||||||
--bp-sm: 480px;
|
--bp-sm: 480px;
|
||||||
@@ -59,31 +57,6 @@
|
|||||||
--accent: var(--color-primary);
|
--accent: var(--color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dark theme overrides: set document.documentElement.dataset.theme = "dark" */
|
|
||||||
[data-theme="dark"] {
|
|
||||||
--color-bg: #0b1220;
|
|
||||||
--color-surface: #0f1724;
|
|
||||||
--color-text: #e6eef8;
|
|
||||||
--color-muted: #9aa5b2;
|
|
||||||
--color-primary: #7c6cff;
|
|
||||||
--color-primary-600: #6d5cff;
|
|
||||||
--color-border: rgba(255, 255, 255, 0.06);
|
|
||||||
--button-bg: #0f1724;
|
|
||||||
--card-bg: linear-gradient(
|
|
||||||
180deg,
|
|
||||||
rgba(18, 20, 28, 0.9),
|
|
||||||
rgba(15, 17, 24, 0.85)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* let the browser apply native form rendering for color-scheme */
|
|
||||||
:root {
|
|
||||||
color-scheme: light;
|
|
||||||
}
|
|
||||||
[data-theme="dark"] {
|
|
||||||
color-scheme: dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Global box sizing & accessible defaults */
|
/* Global box sizing & accessible defaults */
|
||||||
*,
|
*,
|
||||||
*::before,
|
*::before,
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="26.6" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 308"><path fill="#FF3E00" d="M239.682 40.707C211.113-.182 154.69-12.301 113.895 13.69L42.247 59.356a82.198 82.198 0 0 0-37.135 55.056a86.566 86.566 0 0 0 8.536 55.576a82.425 82.425 0 0 0-12.296 30.719a87.596 87.596 0 0 0 14.964 66.244c28.574 40.893 84.997 53.007 125.787 27.016l71.648-45.664a82.182 82.182 0 0 0 37.135-55.057a86.601 86.601 0 0 0-8.53-55.577a82.409 82.409 0 0 0 12.29-30.718a87.573 87.573 0 0 0-14.963-66.244"></path><path fill="#FFF" d="M106.889 270.841c-23.102 6.007-47.497-3.036-61.103-22.648a52.685 52.685 0 0 1-9.003-39.85a49.978 49.978 0 0 1 1.713-6.693l1.35-4.115l3.671 2.697a92.447 92.447 0 0 0 28.036 14.007l2.663.808l-.245 2.659a16.067 16.067 0 0 0 2.89 10.656a17.143 17.143 0 0 0 18.397 6.828a15.786 15.786 0 0 0 4.403-1.935l71.67-45.672a14.922 14.922 0 0 0 6.734-9.977a15.923 15.923 0 0 0-2.713-12.011a17.156 17.156 0 0 0-18.404-6.832a15.78 15.78 0 0 0-4.396 1.933l-27.35 17.434a52.298 52.298 0 0 1-14.553 6.391c-23.101 6.007-47.497-3.036-61.101-22.649a52.681 52.681 0 0 1-9.004-39.849a49.428 49.428 0 0 1 22.34-33.114l71.664-45.677a52.218 52.218 0 0 1 14.563-6.398c23.101-6.007 47.497 3.036 61.101 22.648a52.685 52.685 0 0 1 9.004 39.85a50.559 50.559 0 0 1-1.713 6.692l-1.35 4.116l-3.67-2.693a92.373 92.373 0 0 0-28.037-14.013l-2.664-.809l.246-2.658a16.099 16.099 0 0 0-2.89-10.656a17.143 17.143 0 0 0-18.398-6.828a15.786 15.786 0 0 0-4.402 1.935l-71.67 45.674a14.898 14.898 0 0 0-6.73 9.975a15.9 15.9 0 0 0 2.709 12.012a17.156 17.156 0 0 0 18.404 6.832a15.841 15.841 0 0 0 4.402-1.935l27.345-17.427a52.147 52.147 0 0 1 14.552-6.397c23.101-6.006 47.497 3.037 61.102 22.65a52.681 52.681 0 0 1 9.003 39.848a49.453 49.453 0 0 1-22.34 33.12l-71.664 45.673a52.218 52.218 0 0 1-14.563 6.398"></path></svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.9 KiB |
@@ -1,20 +1,27 @@
|
|||||||
<script>
|
<script>
|
||||||
export let onClick = () => {}
|
export let onClick = () => {};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button on:click={onClick} class="btn">
|
<button onclick={onClick} class="btn">
|
||||||
<slot />
|
<slot />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.btn {
|
.btn {
|
||||||
background: var(--button-bg);
|
background: var(--white);
|
||||||
color: var(--button-text);
|
color: var(--black);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px solid transparent;
|
border: 1.5px solid transparent;
|
||||||
|
border-color: var(--orange);
|
||||||
padding: 0.6em 1.2em;
|
padding: 0.6em 1.2em;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
.btn:hover {
|
||||||
|
background: var(--orange);
|
||||||
}
|
}
|
||||||
.btn:hover { border-color: var(--primary); }
|
|
||||||
</style>
|
</style>
|
||||||
26
src/components/ButtonBorderless.svelte
Normal file
26
src/components/ButtonBorderless.svelte
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<script>
|
||||||
|
export let onClick = () => {};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={onClick} class="btn">
|
||||||
|
<slot />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.btn {
|
||||||
|
background: var(--white);
|
||||||
|
color: var(--black);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1.5px solid transparent;
|
||||||
|
padding: 0.6em 1.2em;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
.btn:hover {
|
||||||
|
background: var(--orange);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<script>
|
|
||||||
export let className = '';
|
|
||||||
export let as = 'div';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:component this={as} class={`card ${className}`}>
|
|
||||||
<slot />
|
|
||||||
</svelte:component>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<script>
|
|
||||||
export let fluid = false; // when true, removes max-width
|
|
||||||
export let className = '';
|
|
||||||
export let as = 'div';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:component this={as} class={`container ${fluid ? 'container--fluid' : ''} ${className}`}>
|
|
||||||
<slot />
|
|
||||||
</svelte:component>
|
|
||||||
71
src/components/Dropdown.svelte
Normal file
71
src/components/Dropdown.svelte
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<script>
|
||||||
|
import Button from "./Button.svelte";
|
||||||
|
import ButtonBorderless from "./ButtonBorderless.svelte";
|
||||||
|
|
||||||
|
// Props
|
||||||
|
export let name = "";
|
||||||
|
export let variant = "default"; // 'default' | 'borderless' aka 'Button' | 'ButtonBorderless'
|
||||||
|
|
||||||
|
let isOpen = false;
|
||||||
|
|
||||||
|
const toggle = () => (isOpen = !isOpen);
|
||||||
|
const close = () => (isOpen = false);
|
||||||
|
|
||||||
|
function handleFocusOut({ relatedTarget, currentTarget }) {
|
||||||
|
if (
|
||||||
|
relatedTarget instanceof HTMLElement &&
|
||||||
|
currentTarget.contains(relatedTarget)
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="relative inline-block" on:focusout={handleFocusOut}>
|
||||||
|
{#if variant === "borderless"}
|
||||||
|
<ButtonBorderless onClick={toggle}>
|
||||||
|
{name}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="w-5 ml-2 mt-1 transition-transform inline-block"
|
||||||
|
style:transform={isOpen ? "rotate(180deg)" : "none"}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="m19.5 8.25-7.5 7.5-7.5-7.5"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</ButtonBorderless>
|
||||||
|
{:else}
|
||||||
|
<Button onClick={toggle}>
|
||||||
|
{name}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="w-5 ml-2 mt-1 transition-transform inline-block"
|
||||||
|
style:transform={isOpen ? "rotate(180deg)" : "none"}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="m19.5 8.25-7.5 7.5-7.5-7.5"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="absolute mt-2 rounded-md shadow-lg bg-white ring-1 ring-black/5 overflow-hidden flex flex-col"
|
||||||
|
style:visibility={isOpen ? "visible" : "hidden"}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<script>
|
|
||||||
export let min = '220px'; // minimum column width
|
|
||||||
export let gap = 'var(--space-3)';
|
|
||||||
export let className = '';
|
|
||||||
export let as = 'div';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:component this={as} class={`grid ${className}`} style={`grid-template-columns: repeat(auto-fit, minmax(${min}, 1fr)); gap: ${gap};`}>
|
|
||||||
<slot />
|
|
||||||
</svelte:component>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<script>
|
|
||||||
// Vertical stack helper. Accepts a gap and alignment so pages can tune spacing.
|
|
||||||
export let gap = 'var(--space-3)';
|
|
||||||
export let align = 'stretch';
|
|
||||||
export let className = '';
|
|
||||||
export let as = 'div';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:component this={as} class={`stack ${className}`} style={`gap: ${gap}; align-items: ${align};`}>
|
|
||||||
<slot />
|
|
||||||
</svelte:component>
|
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
export { default as Container } from './Container.svelte'
|
export { default as Container } from './layout/Container.svelte'
|
||||||
export { default as Card } from './Card.svelte'
|
export { default as Card } from './layout/Card.svelte'
|
||||||
export { default as Stack } from './Stack.svelte'
|
export { default as Stack } from './layout/Stack.svelte'
|
||||||
export { default as Grid } from './Grid.svelte'
|
export { default as Grid } from './layout/Grid.svelte'
|
||||||
|
|
||||||
export { default as Button } from './Button.svelte'
|
export { default as Button } from './Button.svelte'
|
||||||
|
export { default as ButtonBorderless } from './ButtonBorderless.svelte'
|
||||||
|
export { default as Dropdown } from './Dropdown.svelte'
|
||||||
|
|||||||
12
src/components/layout/Card.svelte
Normal file
12
src/components/layout/Card.svelte
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<!--
|
||||||
|
A simple presentational container that renders a `div` with the `card` class.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export let className = "";
|
||||||
|
export let background = "var(--off-white)";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class={`card ${className}`} style="background: {background}">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
15
src/components/layout/Container.svelte
Normal file
15
src/components/layout/Container.svelte
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!--
|
||||||
|
A responsive container that centers content and optionally
|
||||||
|
removes the max-width when `fluid` is true. Use `className` to
|
||||||
|
add additional CSS classes to the root element. Content is
|
||||||
|
projected via the default slot.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export let fluid = false; // true removes max-width
|
||||||
|
export let className = "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class={`container ${fluid ? "container--fluid" : ""} ${className}`}>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
18
src/components/layout/Grid.svelte
Normal file
18
src/components/layout/Grid.svelte
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!--
|
||||||
|
A responsive grid wrapper using CSS Grid. It exposes `min` and
|
||||||
|
`gap` props to control the responsive column minimum width and
|
||||||
|
spacing. Content is projected into the default slot.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export let min = "220px"; // minimum column width
|
||||||
|
export let gap = "var(--space-3)";
|
||||||
|
export let className = "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class={`grid ${className}`}
|
||||||
|
style={`grid-template-columns: repeat(auto-fit, minmax(${min}, 1fr)); gap: ${gap};`}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
13
src/components/layout/Stack.svelte
Normal file
13
src/components/layout/Stack.svelte
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!--
|
||||||
|
A simple stack/column layout that stacks children vertically.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export let gap = "var(--space-3)";
|
||||||
|
export let align = "stretch";
|
||||||
|
export let className = "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class={`stack ${className}`} style={`gap: ${gap}; align-items: ${align};`}>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
16
src/layout/Center.svelte
Normal file
16
src/layout/Center.svelte
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<script>
|
||||||
|
export let dir = "row"; // 'row' | 'col' (default: 'row')
|
||||||
|
export let gapClass = "gap-4";
|
||||||
|
export let className = "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class={"flex " +
|
||||||
|
(dir === "row" ? "flex-row" : "flex-col") +
|
||||||
|
" items-center justify-center " +
|
||||||
|
gapClass +
|
||||||
|
" " +
|
||||||
|
className}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<script>
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonBorderless,
|
||||||
|
Dropdown,
|
||||||
|
Grid,
|
||||||
|
} from "@/components/index.js";
|
||||||
|
import Center from "./Center.svelte";
|
||||||
|
import { navigate, getPath, currentLang, text, switchLang } from "$lib";
|
||||||
|
|
||||||
|
// Icon imports (Lucide)
|
||||||
|
import Coffee from "lucide-svelte/icons/coffee";
|
||||||
|
import CalendarClock from "lucide-svelte/icons/calendar-clock";
|
||||||
|
import Presentation from "lucide-svelte/icons/presentation";
|
||||||
|
import Swords from "lucide-svelte/icons/swords";
|
||||||
|
import Lectern from "lucide-svelte/icons/lectern";
|
||||||
|
import Bot from "lucide-svelte/icons/bot";
|
||||||
|
import HandHeart from "lucide-svelte/icons/hand-heart";
|
||||||
|
import Trophy from "lucide-svelte/icons/trophy";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<nav class="w-full h-16">
|
||||||
|
<Center gapClass="gap-4">
|
||||||
|
<Button onClick={() => navigate("/")}>Home</Button>
|
||||||
|
<ButtonBorderless onClick={() => navigate("/about")}
|
||||||
|
>About</ButtonBorderless
|
||||||
|
>
|
||||||
|
<Dropdown name={$text.nav.about} variant="borderless">
|
||||||
|
<ButtonBorderless onClick={() => navigate("/mis-teeme")}
|
||||||
|
>{$text.nav.aboutPages.info}</ButtonBorderless
|
||||||
|
>
|
||||||
|
<ButtonBorderless onClick={() => navigate("/liitu-meiega")}
|
||||||
|
><Bot />{$text.nav.aboutPages.join}</ButtonBorderless
|
||||||
|
>
|
||||||
|
<ButtonBorderless onClick={() => navigate("/mentorid")}
|
||||||
|
><HandHeart />{$text.nav.aboutPages.mentors}</ButtonBorderless
|
||||||
|
>
|
||||||
|
<ButtonBorderless onClick={() => navigate("/juhatus")}
|
||||||
|
><Lectern />{$text.nav.aboutPages.board}</ButtonBorderless
|
||||||
|
>
|
||||||
|
</Dropdown>
|
||||||
|
<Dropdown name={$text.nav.events} variant="borderless">
|
||||||
|
<ButtonBorderless onClick={() => navigate("/kalender")}
|
||||||
|
><CalendarClock />{$text.nav.eventsPages.calendar}</ButtonBorderless
|
||||||
|
>
|
||||||
|
<ButtonBorderless
|
||||||
|
onClick={() => navigate("https://asikarikas.ee/", { external: true })}
|
||||||
|
><Trophy />ASI Karikas</ButtonBorderless
|
||||||
|
>
|
||||||
|
<ButtonBorderless onClick={() => navigate("/mentorid")}
|
||||||
|
><Presentation />{$text.nav.eventsPages.workshops}</ButtonBorderless
|
||||||
|
>
|
||||||
|
<ButtonBorderless onClick={() => navigate("/rebased")}
|
||||||
|
><Swords />{$text.nav.eventsPages.fresh}</ButtonBorderless
|
||||||
|
>
|
||||||
|
<ButtonBorderless
|
||||||
|
onClick={() =>
|
||||||
|
navigate("https://remondikohvik.lapikud.ee/", { external: true })}
|
||||||
|
><Coffee />{$text.nav.eventsPages.repair}</ButtonBorderless
|
||||||
|
>
|
||||||
|
</Dropdown>
|
||||||
|
</Center>
|
||||||
|
</nav>
|
||||||
|
</Grid>
|
||||||
|
|||||||
35
src/lib/i18n.js
Normal file
35
src/lib/i18n.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { writable } from 'svelte/store';
|
||||||
|
|
||||||
|
// Load saved language or default to 'est'
|
||||||
|
const savedLang = typeof window !== 'undefined'
|
||||||
|
? localStorage.getItem('language') || 'est'
|
||||||
|
: 'est';
|
||||||
|
|
||||||
|
// Store for current language
|
||||||
|
export const currentLang = writable(savedLang);
|
||||||
|
|
||||||
|
// Store for translations
|
||||||
|
export const text = writable({});
|
||||||
|
|
||||||
|
// Load translations for a specific language
|
||||||
|
async function loadTranslations(lang) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/locales/${lang}.json`);
|
||||||
|
const data = await response.json();
|
||||||
|
text.set(data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to load translations for ${lang}:`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize translations
|
||||||
|
loadTranslations(savedLang);
|
||||||
|
|
||||||
|
// Function to switch language
|
||||||
|
export function switchLang(lang) {
|
||||||
|
currentLang.set(lang);
|
||||||
|
loadTranslations(lang);
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
localStorage.setItem('language', lang);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
src/lib/index.js
Normal file
4
src/lib/index.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export { navigate, goBack, reload, getPath, getQuery } from './router/router.js';
|
||||||
|
export { default as Router } from './router/Router.svelte';
|
||||||
|
|
||||||
|
export { currentLang, text, switchLang } from './i18n.js';
|
||||||
@@ -2,6 +2,11 @@
|
|||||||
<!-- unless the router is broken 👉👈 -->
|
<!-- unless the router is broken 👉👈 -->
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
export function routeTo(path) {
|
||||||
|
window.history.pushState({}, "", path);
|
||||||
|
window.dispatchEvent(new PopStateEvent("popstate"));
|
||||||
|
}
|
||||||
|
|
||||||
let { routes } = $props();
|
let { routes } = $props();
|
||||||
|
|
||||||
let currentPath = $state(window.location.pathname);
|
let currentPath = $state(window.location.pathname);
|
||||||
44
src/lib/router/router.js
Normal file
44
src/lib/router/router.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
*/
|
||||||
|
export function navigate(path, external = false) {
|
||||||
|
if (external) {
|
||||||
|
window.location.href = path;
|
||||||
|
} else {
|
||||||
|
window.history.pushState({}, "", path);
|
||||||
|
window.dispatchEvent(new PopStateEvent('popstate'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go back in browser history
|
||||||
|
*/
|
||||||
|
export function goBack() {
|
||||||
|
window.history.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reload the current page
|
||||||
|
*/
|
||||||
|
export function reload() {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current pathname
|
||||||
|
* @returns {string} Current path
|
||||||
|
*/
|
||||||
|
export function getPath() {
|
||||||
|
return window.location.pathname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get URL query parameters as an object
|
||||||
|
* @returns {Object} Query parameters
|
||||||
|
*/
|
||||||
|
export function getQuery() {
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
return Object.fromEntries(params.entries());
|
||||||
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
// THEME STORE for LIGHT / DARK mode
|
|
||||||
|
|
||||||
import { writable } from 'svelte/store'
|
|
||||||
|
|
||||||
const init = (() => {
|
|
||||||
try {
|
|
||||||
const stored = localStorage.getItem('theme')
|
|
||||||
if (stored === 'light' || stored === 'dark') return stored
|
|
||||||
} catch (e) { }
|
|
||||||
return (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light'
|
|
||||||
})()
|
|
||||||
|
|
||||||
export const theme = writable(init)
|
|
||||||
|
|
||||||
theme.subscribe(value => {
|
|
||||||
try { localStorage.setItem('theme', value) } catch (e) { }
|
|
||||||
document.documentElement.dataset.theme = value
|
|
||||||
})
|
|
||||||
|
|
||||||
export function toggle() {
|
|
||||||
theme.update(t => t === 'dark' ? 'light' : 'dark')
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
<h1>Demo Page</h1>
|
|
||||||
<a href="/">Back to Home</a>
|
|
||||||
@@ -1,5 +1,47 @@
|
|||||||
<h1>Home</h1>
|
<script>
|
||||||
<nav>
|
import {
|
||||||
<a href="/demo">Demo</a>
|
Button,
|
||||||
<a href="/contact">Contact</a>
|
ButtonBorderless,
|
||||||
</nav>
|
Container,
|
||||||
|
Card,
|
||||||
|
Stack,
|
||||||
|
Grid,
|
||||||
|
} from "@/components/index.js";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Container>
|
||||||
|
<Stack gap="var(--space-6)">
|
||||||
|
<Card>
|
||||||
|
<h1>Kes me oleme?</h1>
|
||||||
|
<p>
|
||||||
|
Organisatsioon loodi 2002. aastal informaatika tudengite poolt, kelle
|
||||||
|
erialatunnuseks oli “LAP”. Targad mehed otsustasid, et järelikult on nad
|
||||||
|
“Lapikud”.
|
||||||
|
</p>
|
||||||
|
<Button href="/docs/getting-started">Get Started</Button>
|
||||||
|
<ButtonBorderless href="/docs/components"
|
||||||
|
>Explore Components</ButtonBorderless
|
||||||
|
>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Grid min="250px" gap="var(--space-4)">
|
||||||
|
<Card>
|
||||||
|
<h2>Mis on HELPDESK?</h2>
|
||||||
|
<p>
|
||||||
|
HELPDESK on MTÜ Lapikute poolt pakutav arvutiabiteenus. Teenus on
|
||||||
|
suunatud tudengitele, õppejõududele ning kõikidele huvilistele ka
|
||||||
|
väljaspool Tallinna Tehnikaülikooli. Meie meeskond koosneb kogenud ja
|
||||||
|
nutikatest Tallinna Tehnikaülikooli IT-tudengitest.
|
||||||
|
</p>
|
||||||
|
</Card>
|
||||||
|
<Card>
|
||||||
|
<h2>Mis teenuseid osutame?</h2>
|
||||||
|
<p>
|
||||||
|
Arvuti riistvara diagnostika ja remont Arvuti riistvara hooldus
|
||||||
|
Tarkvara diagnostika ja seadistamine Tarkvara paigaldamine Muu
|
||||||
|
elektroonika parandamine
|
||||||
|
</p>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
</Stack>
|
||||||
|
</Container>
|
||||||
|
|||||||
1
src/routes/Test.svelte
Normal file
1
src/routes/Test.svelte
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<div>testing</div>
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
// ADD PAGES HERE TO REGISTER ROUTES
|
// ADD PAGES HERE TO REGISTER ROUTES
|
||||||
// examples: '/page', '/page/:id'
|
// examples: '/page', '/page/:id'
|
||||||
|
|
||||||
import Demo from './Demo.svelte'
|
|
||||||
import Home from './Home.svelte'
|
import Home from './Home.svelte'
|
||||||
|
import Test from './Test.svelte'
|
||||||
|
|
||||||
export const routes = {
|
export const routes = {
|
||||||
'/': Home,
|
'/': Home,
|
||||||
'/demo': Demo,
|
'/juhatus': Test,
|
||||||
}
|
}
|
||||||
@@ -8,4 +8,10 @@ export default defineConfig({
|
|||||||
server: {
|
server: {
|
||||||
historyApiFallback: true,
|
historyApiFallback: true,
|
||||||
},
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': '/src',
|
||||||
|
'$lib': '/src/lib'
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user