formatting

This commit is contained in:
nub31
2026-03-17 17:12:45 +01:00
parent 794a0549ab
commit ceb05f4a75
36 changed files with 2535 additions and 2747 deletions

5
.prettierrc Normal file
View File

@@ -0,0 +1,5 @@
{
"plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}

View File

@@ -7,10 +7,7 @@
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=Roboto+Slab:wght@400;500;600;700;800;900&display=swap" rel="stylesheet" />
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=Roboto+Slab:wght@400;500;600;700;800;900&display=swap"
rel="stylesheet"
/>
<title>Minibusservice</title> <title>Minibusservice</title>
</head> </head>
<body> <body>

29
package-lock.json generated
View File

@@ -14,6 +14,8 @@
"@types/leaflet": "^1.9.21", "@types/leaflet": "^1.9.21",
"@types/node": "^24.12.0", "@types/node": "^24.12.0",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"prettier": "^3.8.1",
"prettier-plugin-svelte": "^3.5.1",
"svelte": "^5.53.7", "svelte": "^5.53.7",
"svelte-check": "^4.4.5", "svelte-check": "^4.4.5",
"tailwind-merge": "^3.5.0", "tailwind-merge": "^3.5.0",
@@ -1593,6 +1595,33 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/prettier": {
"version": "3.8.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz",
"integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/prettier-plugin-svelte": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.5.1.tgz",
"integrity": "sha512-65+fr5+cgIKWKiqM1Doum4uX6bY8iFCdztvvp2RcF+AJoieaw9kJOFMNcJo/bkmKYsxFaM9OsVZK/gWauG/5mg==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"prettier": "^3.0.0",
"svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0"
}
},
"node_modules/readdirp": { "node_modules/readdirp": {
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",

View File

@@ -7,7 +7,8 @@
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build",
"preview": "vite preview", "preview": "vite preview",
"check": "svelte-check --tsconfig ./tsconfig.app.json && tsc -p tsconfig.node.json" "check": "svelte-check --tsconfig ./tsconfig.app.json && tsc -p tsconfig.node.json",
"format": "prettier --write ."
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/vite-plugin-svelte": "^7.0.0", "@sveltejs/vite-plugin-svelte": "^7.0.0",
@@ -16,11 +17,21 @@
"@types/leaflet": "^1.9.21", "@types/leaflet": "^1.9.21",
"@types/node": "^24.12.0", "@types/node": "^24.12.0",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"prettier": "^3.8.1",
"prettier-plugin-svelte": "^3.5.1",
"svelte": "^5.53.7", "svelte": "^5.53.7",
"svelte-check": "^4.4.5", "svelte-check": "^4.4.5",
"tailwind-merge": "^3.5.0", "tailwind-merge": "^3.5.0",
"tailwindcss": "^0.0.0-insiders.aaaefe8", "tailwindcss": "^0.0.0-insiders.aaaefe8",
"typescript": "~5.9.3", "typescript": "~5.9.3",
"vite": "^8.0.0" "vite": "^8.0.0"
},
"prettier": {
"trailingComma": "none",
"tabWidth": 4,
"printWidth": 180,
"plugins": [
"prettier-plugin-svelte"
]
} }
} }

View File

@@ -25,9 +25,7 @@
<Router> <Router>
{#snippet notfound()} {#snippet notfound()}
<h1>Not found</h1> <h1>Not found</h1>
<p> <p>Sorry, the page you are looking for does not exist.</p>
Sorry, the page you are looking for does not exist.
</p>
<p>Return to <a href="/">home</a>.</p> <p>Return to <a href="/">home</a>.</p>
{/snippet} {/snippet}
</Router> </Router>

View File

@@ -23,7 +23,5 @@
{/each} {/each}
</div> </div>
<div class="mt-8 text-center font-semibold">Org nr: 816 230 942</div> <div class="mt-8 text-center font-semibold">Org nr: 816 230 942</div>
<div class="mt-2 text-center font-semibold"> <div class="mt-2 text-center font-semibold">© 2026 minibusservice.no - All Rights Reserved.</div>
© 2026 minibusservice.no - All Rights Reserved.
</div>
</footer> </footer>

View File

@@ -15,49 +15,30 @@
} }
</script> </script>
<header <header class="sticky top-0 z-20 flex h-16 justify-center border-b-2 border-contrast-100 bg-primary-100 shadow-lg">
class="sticky top-0 z-20 flex h-16 justify-center border-b-2 border-contrast-100 bg-primary-100 shadow-lg" <div class="flex w-full max-w-7xl flex-row items-center justify-between p-4">
>
<div
class="flex w-full max-w-7xl flex-row items-center justify-between p-4"
>
<a class="h-full grow" href="/"> <a class="h-full grow" href="/">
<Logo /> <Logo />
</a> </a>
<ul <ul class="hidden flex-row justify-end gap-10 font-medium uppercase md:text-lg lg:flex">
class="hidden flex-row justify-end gap-10 font-medium uppercase md:text-lg lg:flex"
>
{#each Routes.topbarRoutes as route} {#each Routes.topbarRoutes as route}
<li> <li>
<a <a class:border-b-2={isCurrentPath(route.url)} class="border-b-0 border-accent transition-colors hover:text-accent" href={route.url} target={route.target}>
class:border-b-2={isCurrentPath(route.url)}
class="border-b-0 border-accent transition-colors hover:text-accent"
href={route.url}
target={route.target}
>
{route.text} {route.text}
</a> </a>
</li> </li>
{/each} {/each}
</ul> </ul>
<div <div class="ml-12 flex aspect-square h-full items-center justify-center p-1">
class="ml-12 flex aspect-square h-full items-center justify-center p-1"
>
<button <button
class="hamburger-icon relative inline-block h-full w-full cursor-pointer text-contrast-100" class="hamburger-icon relative inline-block h-full w-full cursor-pointer text-contrast-100"
aria-label="open sidebar" aria-label="open sidebar"
class:open={sidebarOpen} class:open={sidebarOpen}
on:click={toggleMenuOpen} on:click={toggleMenuOpen}
> >
<div <div class="line absolute top-0 h-0.5 w-full origin-top-left rounded-full bg-contrast-900 transition-all"></div>
class="line absolute top-0 h-0.5 w-full origin-top-left rounded-full bg-contrast-900 transition-all" <div class="line middle absolute top-1/2 h-0.5 w-full -translate-y-1/2 rounded-full bg-contrast-900 transition-all delay-100"></div>
></div> <div class="line absolute bottom-0 h-0.5 w-full origin-bottom-left rounded-full bg-contrast-900 transition-all"></div>
<div
class="line middle absolute top-1/2 h-0.5 w-full -translate-y-1/2 rounded-full bg-contrast-900 transition-all delay-100"
></div>
<div
class="line absolute bottom-0 h-0.5 w-full origin-bottom-left rounded-full bg-contrast-900 transition-all"
></div>
</button> </button>
</div> </div>
</div> </div>
@@ -67,9 +48,7 @@
transition:slide={{ axis: "x" }} transition:slide={{ axis: "x" }}
class="fixed bottom-14 right-0 top-16 z-10 flex max-w-full flex-col overflow-auto border-l-2 border-contrast-100 bg-primary-100 px-4 py-8 shadow-lg sm:bottom-0" class="fixed bottom-14 right-0 top-16 z-10 flex max-w-full flex-col overflow-auto border-l-2 border-contrast-100 bg-primary-100 px-4 py-8 shadow-lg sm:bottom-0"
> >
<ul <ul class="flex grow flex-col gap-2 pr-20 text-lg font-medium lg:text-xl">
class="flex grow flex-col gap-2 pr-20 text-lg font-medium lg:text-xl"
>
{#each Routes.sidebarRoutes as route} {#each Routes.sidebarRoutes as route}
<li> <li>
<a <a
@@ -102,18 +81,12 @@
<slot /> <slot />
<!-- Mobile navigation --> <!-- Mobile navigation -->
<nav <nav class="sticky bottom-0 z-10 flex h-14 flex-row items-center justify-around border-t-2 border-contrast-100 bg-primary-100 px-2 text-xs shadow-t-lg sm:hidden">
class="sticky bottom-0 z-10 flex h-14 flex-row items-center justify-around border-t-2 border-contrast-100 bg-primary-100 px-2 text-xs shadow-t-lg sm:hidden"
>
{#each Routes.topbarRoutes as route} {#each Routes.topbarRoutes as route}
<a <a
href={route.url} href={route.url}
target={route.target} target={route.target}
class={`flex flex-col items-center decoration-accent transition-opacity ${ class={`flex flex-col items-center decoration-accent transition-opacity ${isCurrentPath(route.url) ? "underline opacity-100" : "opacity-50"}`}
isCurrentPath(route.url)
? "underline opacity-100"
: "opacity-50"
}`}
> >
<img src={route.icon} alt={route.text} class="h-6 dark:invert" /> <img src={route.icon} alt={route.text} class="h-6 dark:invert" />
<span> {route.text} </span> <span> {route.text} </span>

View File

@@ -8,26 +8,16 @@
<p class="pt-2 font-medium opacity-70"> <p class="pt-2 font-medium opacity-70">
Spørsmål?<br />Kontakt oss via tlf eller e-post Spørsmål?<br />Kontakt oss via tlf eller e-post
</p> </p>
<Link <Link class="w-fit font-bold text-accent hover:underline" href="tel:45256161">Tlf: +47 45 25 61 61</Link>
class="w-fit font-bold text-accent hover:underline" <Link class="w-fit font-bold text-accent hover:underline" href="mailto:minibusstur@hotmail.com">E-post: minibusstur@hotmail.com</Link>
href="tel:45256161"
>
Tlf: +47 45 25 61 61
</Link>
<Link
class="w-fit font-bold text-accent hover:underline"
href="mailto:minibusstur@hotmail.com"
>
E-post: minibusstur@hotmail.com
</Link>
<MapPoint <MapPoint
class="card mt-5 min-h-140 grow overflow-hidden rounded-md border-2" class="card mt-5 min-h-140 grow overflow-hidden rounded-md border-2"
coordinates={[ coordinates={[
{ {
latitude: 62.48303957042255, latitude: 62.48303957042255,
longitude: 6.8108274964451745, longitude: 6.8108274964451745
}, }
]} ]}
/> />
</div> </div>

View File

@@ -23,23 +23,19 @@
iconSize: [32, 32], iconSize: [32, 32],
iconAnchor: [16, 32], iconAnchor: [16, 32],
popupAnchor: [-3, -76], popupAnchor: [-3, -76]
}); });
map = L.map(mapElement); map = L.map(mapElement);
if (coordinates.length >= 1) { if (coordinates.length >= 1) {
map.setView( map.setView([coordinates[0].latitude, coordinates[0].longitude], 15);
[coordinates[0].latitude, coordinates[0].longitude],
15,
);
} }
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 18, maxZoom: 18,
attribution: attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors', id: "base"
id: "base",
}).addTo(map); }).addTo(map);
updateMarkers(); updateMarkers();
@@ -51,12 +47,12 @@
function addMarker(point: MarkerPoint) { function addMarker(point: MarkerPoint) {
let marker = L.marker([point.latitude, point.longitude], { let marker = L.marker([point.latitude, point.longitude], {
icon: icon, icon: icon
}); });
if (point.tooltip) if (point.tooltip)
marker.bindTooltip(point.tooltip, { marker.bindTooltip(point.tooltip, {
direction: "bottom", direction: "bottom"
}); });
markers.push(marker); markers.push(marker);
@@ -71,7 +67,7 @@
coordinates.forEach(addMarker); coordinates.forEach(addMarker);
map?.flyToBounds(L.featureGroup(markers).getBounds(), { map?.flyToBounds(L.featureGroup(markers).getBounds(), {
duration: 1, duration: 1
}); });
} }
} }
@@ -79,7 +75,4 @@
$: coordinates && updateMarkers(); $: coordinates && updateMarkers();
</script> </script>
<div <div bind:this={mapElement} class={twMerge("z-0 h-full w-full", $$restProps["class"])}></div>
bind:this={mapElement}
class={twMerge("z-0 h-full w-full", $$restProps["class"])}
></div>

View File

@@ -2,6 +2,11 @@
import { SvelteMap } from "svelte/reactivity"; import { SvelteMap } from "svelte/reactivity";
import { onMount, type Component, type Snippet } from "svelte"; import { onMount, type Component, type Snippet } from "svelte";
export class RouteError extends Error {}
export class MissingRouteError extends RouteError {}
export class RouteFormatError extends RouteError {}
export class DuplicateRouteError extends RouteError {}
type RouteInfo = { type RouteInfo = {
path: string; path: string;
pattern: RegExp; pattern: RegExp;
@@ -62,25 +67,19 @@
*/ */
export function route(path: string, component: Component<{}>): void { export function route(path: string, component: Component<{}>): void {
if (routes.has(path)) { if (routes.has(path)) {
console.warn(`Route already registered for path: '${path}'.`); throw new DuplicateRouteError(`Route already registered for path: '${path}'.`);
} }
const params = Array.from(path.matchAll(/\[([^\]]+)\]/g)).map( const params = Array.from(path.matchAll(/\[([^\]]+)\]/g)).map((x) => x[1]);
(x) => x[1],
);
routes.set(path, { routes.set(path, {
pattern: new RegExp(createRoutePattern(path)), pattern: new RegExp(createRoutePattern(path)),
path: path, path: path,
paramNames: params, paramNames: params,
component: component, component: component
}); });
} }
export class RouteError extends Error {}
export class MissingRouteError extends RouteError {}
export class RouteFormatError extends RouteError {}
export function isCurrentPath(path: string): boolean { export function isCurrentPath(path: string): boolean {
if (!currentRoute) { if (!currentRoute) {
return false; return false;
@@ -100,9 +99,7 @@
export function paramString(name: string): string { export function paramString(name: string): string {
const value = currentParams[name]; const value = currentParams[name];
if (!value) { if (!value) {
throw new MissingRouteError( throw new MissingRouteError(`Route does not have a parameter matching the name '${name}''`);
`Route does not have a parameter matching the name '${name}''`,
);
} }
return value; return value;
@@ -115,9 +112,7 @@
const value = paramString(name); const value = paramString(name);
const parsed = parseInt(value, 10); const parsed = parseInt(value, 10);
if (Number.isNaN(parsed)) { if (Number.isNaN(parsed)) {
throw new RouteFormatError( throw new RouteFormatError(`parameter ${value} could not be parsed as an integer`);
`parameter ${value} could not be parsed as an integer`,
);
} }
return parsed; return parsed;
@@ -129,10 +124,7 @@
*/ */
export function queryString(name: string): string | null; export function queryString(name: string): string | null;
export function queryString(name: string, defaultValue: string): string; export function queryString(name: string, defaultValue: string): string;
export function queryString( export function queryString(name: string, defaultValue?: string): string | null {
name: string,
defaultValue?: string,
): string | null {
const value = currentUrl.searchParams.get(name); const value = currentUrl.searchParams.get(name);
if (value) { if (value) {
return value; return value;
@@ -147,10 +139,7 @@
*/ */
export function queryNumber(name: string): number | null; export function queryNumber(name: string): number | null;
export function queryNumber(name: string, defaultValue: number): number; export function queryNumber(name: string, defaultValue: number): number;
export function queryNumber( export function queryNumber(name: string, defaultValue?: number): number | null {
name: string,
defaultValue?: number,
): number | null {
const value = currentUrl.searchParams.get(name); const value = currentUrl.searchParams.get(name);
if (value) { if (value) {
@@ -179,7 +168,7 @@
event.intercept({ event.intercept({
handler: async () => { handler: async () => {
currentUrl = new URL(event.destination.url); currentUrl = new URL(event.destination.url);
}, }
}); });
} }
@@ -188,10 +177,7 @@
return () => { return () => {
// @ts-ignore // @ts-ignore
window.navigation.removeEventListener( window.navigation.removeEventListener("navigate", handleNavigate);
"navigate",
handleNavigate,
);
}; };
} else { } else {
function refresh() { function refresh() {
@@ -204,14 +190,12 @@
const result = target.apply(thisArg, argArray); const result = target.apply(thisArg, argArray);
refresh(); refresh();
return result; return result;
}, }
}); });
} }
window.history.pushState = makeProxy(window.history.pushState); window.history.pushState = makeProxy(window.history.pushState);
window.history.replaceState = makeProxy( window.history.replaceState = makeProxy(window.history.replaceState);
window.history.replaceState,
);
window.history.go = makeProxy(window.history.go); window.history.go = makeProxy(window.history.go);
window.history.forward = makeProxy(window.history.forward); window.history.forward = makeProxy(window.history.forward);
window.history.back = makeProxy(window.history.back); window.history.back = makeProxy(window.history.back);

View File

@@ -10,24 +10,10 @@
<g fill="none" fill-rule="evenodd"> <g fill="none" fill-rule="evenodd">
<g transform="translate(1 1)"> <g transform="translate(1 1)">
<path d="M36 18c0-9.94-8.06-18-18-18" id="Oval-2" stroke="url(#a)" stroke-width="2"> <path d="M36 18c0-9.94-8.06-18-18-18" id="Oval-2" stroke="url(#a)" stroke-width="2">
<animateTransform <animateTransform attributeName="transform" type="rotate" from="0 18 18" to="360 18 18" dur="0.9s" repeatCount="indefinite" />
attributeName="transform"
type="rotate"
from="0 18 18"
to="360 18 18"
dur="0.9s"
repeatCount="indefinite"
/>
</path> </path>
<circle fill="currentColor" cx="36" cy="18" r="1"> <circle fill="currentColor" cx="36" cy="18" r="1">
<animateTransform <animateTransform attributeName="transform" type="rotate" from="0 18 18" to="360 18 18" dur="0.9s" repeatCount="indefinite" />
attributeName="transform"
type="rotate"
from="0 18 18"
to="360 18 18"
dur="0.9s"
repeatCount="indefinite"
/>
</circle> </circle>
</g> </g>
</g> </g>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -9,29 +9,15 @@
<div class="flex items-center gap-1"> <div class="flex items-center gap-1">
{#if leftIcon} {#if leftIcon}
<img <img src={leftIcon} class={`h-6 ${invertColor && "dark:invert"}`} alt="" />
src={leftIcon}
class={`h-6 ${invertColor && "dark:invert"}`}
alt=""
/>
{/if} {/if}
<label class="relative inline-flex cursor-pointer items-center"> <label class="relative inline-flex cursor-pointer items-center">
<input <input on:change {checked} type="checkbox" value="" class="peer sr-only" />
on:change
{checked}
type="checkbox"
value=""
class="peer sr-only"
/>
<div <div
class="h-6 w-11 rounded-full border-2 border-contrast-100 outline-2 transition-colors after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:border-2 after:border-contrast-100 after:bg-contrast-900 after:transition-all after:content-[''] peer-checked:bg-accent peer-checked:after:translate-x-full dark:peer-focus:ring-accent" class="h-6 w-11 rounded-full border-2 border-contrast-100 outline-2 transition-colors after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:border-2 after:border-contrast-100 after:bg-contrast-900 after:transition-all after:content-[''] peer-checked:bg-accent peer-checked:after:translate-x-full dark:peer-focus:ring-accent"
></div> ></div>
</label> </label>
{#if rightIcon} {#if rightIcon}
<img <img src={rightIcon} class={`h-6 ${invertColor && "dark:invert"}`} alt="" />
src={rightIcon}
class={`h-6 ${invertColor && "dark:invert"}`}
alt=""
/>
{/if} {/if}
</div> </div>

View File

@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import Spinner from '../Spinner.svelte'; import Spinner from "../Spinner.svelte";
import { twMerge } from 'tailwind-merge'; import { twMerge } from "tailwind-merge";
/** @description Disallow clicking and reduce opacity **/ /** @description Disallow clicking and reduce opacity **/
export let disabled = false; export let disabled = false;
@@ -15,8 +15,8 @@
class:opacity-50={disabled || loading} class:opacity-50={disabled || loading}
class:cursor-not-allowed={disabled || loading} class:cursor-not-allowed={disabled || loading}
class={twMerge( class={twMerge(
'relative rounded-md border-2 border-contrast-200 bg-primary-300 px-4 py-2 transition-colors hover:border-contrast-900 dark:border-contrast-100 dark:hover:border-accent', "relative rounded-md border-2 border-contrast-200 bg-primary-300 px-4 py-2 transition-colors hover:border-contrast-900 dark:border-contrast-100 dark:hover:border-accent",
$$restProps['class'] $$restProps["class"]
)} )}
> >
<span class:opacity-0={loading}> <span class:opacity-0={loading}>

View File

@@ -1,10 +1,10 @@
<script lang="ts" generics="T"> <script lang="ts" generics="T">
import { twMerge } from 'tailwind-merge'; import { twMerge } from "tailwind-merge";
export let items: T[]; export let items: T[];
/** @description Tailwind classes for styling the button colors */ /** @description Tailwind classes for styling the button colors */
export let buttonClass = ''; export let buttonClass = "";
let index = 0; let index = 0;
@@ -17,11 +17,7 @@
}; };
</script> </script>
<div <div style={`--index: ${index}`} {...$$restProps} class={twMerge("inline-flex w-full gap-5 overflow-auto sm:overflow-hidden", $$restProps["class"])}>
style={`--index: ${index}`}
{...$$restProps}
class={twMerge('inline-flex w-full gap-5 overflow-auto sm:overflow-hidden', $$restProps['class'])}
>
{#each items as item, index} {#each items as item, index}
<div class="carousel transition-transform"> <div class="carousel transition-transform">
<slot {item} {index} /> <slot {item} {index} />
@@ -34,7 +30,7 @@
<div class="mt-2 flex justify-between md:text-lg"> <div class="mt-2 flex justify-between md:text-lg">
<button <button
class={twMerge( class={twMerge(
'rounded-md border-2 border-contrast-100 bg-primary-300 px-4 py-2 transition-colors hover:border-contrast-200 dark:hover:border-accent', "rounded-md border-2 border-contrast-100 bg-primary-300 px-4 py-2 transition-colors hover:border-contrast-200 dark:hover:border-accent",
buttonClass buttonClass
)} )}
on:click={prev} on:click={prev}
@@ -43,7 +39,7 @@
</button> </button>
<button <button
class={twMerge( class={twMerge(
'rounded-md border-2 border-contrast-100 bg-primary-300 px-4 py-2 transition-colors hover:border-contrast-200 dark:hover:border-accent', "rounded-md border-2 border-contrast-100 bg-primary-300 px-4 py-2 transition-colors hover:border-contrast-200 dark:hover:border-accent",
buttonClass buttonClass
)} )}
on:click={next} on:click={next}

View File

@@ -1,25 +1,14 @@
<script lang="ts"> <script lang="ts">
import { twMerge } from 'tailwind-merge'; import { twMerge } from "tailwind-merge";
export let layout: 'narrow' | 'wide' = 'wide'; export let layout: "narrow" | "wide" = "wide";
</script> </script>
{#if layout === 'wide'} {#if layout === "wide"}
<svg <svg xmlns="http://www.w3.org/2000/svg" class={twMerge("h-full", $$restProps["class"])} {...$$restProps} viewBox="0 0 1840.81 395.57">
xmlns="http://www.w3.org/2000/svg" <path fill="currentColor" d="M102,153.89,50.09,81.21V191.75H.34V6.59H50.09l64.66,94.79L179.42,6.59h49.74V191.75H179.42V81.21l-51.95,72.68Z" />
class={twMerge('h-full', $$restProps['class'])}
{...$$restProps}
viewBox="0 0 1840.81 395.57"
>
<path
fill="currentColor"
d="M102,153.89,50.09,81.21V191.75H.34V6.59H50.09l64.66,94.79L179.42,6.59h49.74V191.75H179.42V81.21l-51.95,72.68Z"
/>
<path fill="currentColor" d="M336.11,6.59V191.75H286.36V6.59Z" /> <path fill="currentColor" d="M336.11,6.59V191.75H286.36V6.59Z" />
<path <path fill="currentColor" d="M535.35,125.42V6.59H585.1V191.75H535.35l-97-118.83V191.75H388.61V6.59h49.74Z" />
fill="currentColor"
d="M535.35,125.42V6.59H585.1V191.75H535.35l-97-118.83V191.75H388.61V6.59h49.74Z"
/>
<path fill="currentColor" d="M692,6.59V191.75H642.3V6.59Z" /> <path fill="currentColor" d="M692,6.59V191.75H642.3V6.59Z" />
<path <path
fill="currentColor" fill="currentColor"
@@ -37,34 +26,22 @@
fill="#ff1d25" fill="#ff1d25"
d="M846.11,350.74c0-9.9-8.84-11.37-33.26-12-21.48-.63-68.22-2.11-68.22-43.16v-2.74c0-24.21,15.58-45.69,69.06-45.69h7.58a222,222,0,0,1,55,6.95v34.74c-20.42-4.84-40.43-7.79-61.06-7.79-30.53,0-32.63,6.95-32.63,11.79,0,10.11,9.26,11.58,33.05,12.21,20,.42,68.43,1.9,68.43,43.37v2.74c0,24-15.58,45.48-69.27,45.48h-7.58A305.66,305.66,0,0,1,744,389.9V354.53c22.74,5.05,48.21,8.42,69.69,8.42C843.79,363,846.11,356,846.11,350.74Z" d="M846.11,350.74c0-9.9-8.84-11.37-33.26-12-21.48-.63-68.22-2.11-68.22-43.16v-2.74c0-24.21,15.58-45.69,69.06-45.69h7.58a222,222,0,0,1,55,6.95v34.74c-20.42-4.84-40.43-7.79-61.06-7.79-30.53,0-32.63,6.95-32.63,11.79,0,10.11,9.26,11.58,33.05,12.21,20,.42,68.43,1.9,68.43,43.37v2.74c0,24-15.58,45.48-69.27,45.48h-7.58A305.66,305.66,0,0,1,744,389.9V354.53c22.74,5.05,48.21,8.42,69.69,8.42C843.79,363,846.11,356,846.11,350.74Z"
/> />
<path <path fill="#ff1d25" d="M1056.87,285.05H959.81V306.1h76v33.69h-76v18.95h97.06v33.69h-135V251.36h135Z" />
fill="#ff1d25"
d="M1056.87,285.05H959.81V306.1h76v33.69h-76v18.95h97.06v33.69h-135V251.36h135Z"
/>
<path <path
fill="#ff1d25" fill="#ff1d25"
d="M1201.09,392.43l-28.21-44.22c-15,0-29.06,0-42.53-2.1v46.32h-37.9V251.36a707.77,707.77,0,0,1,77.06-4.21h5.89c47.17,0,60.22,20.85,60.22,46.32v8.42c0,17.69-5.9,33.06-24,40.85l26.1,41.26v8.43Zm-70.74-109.7v29.9a266.16,266.16,0,0,0,33.05,1.9c33.69,0,34.32-5.9,34.32-19.16,0-7.58-.21-14.53-27.79-14.53C1160.25,280.84,1144.25,281.47,1130.35,282.73Z" d="M1201.09,392.43l-28.21-44.22c-15,0-29.06,0-42.53-2.1v46.32h-37.9V251.36a707.77,707.77,0,0,1,77.06-4.21h5.89c47.17,0,60.22,20.85,60.22,46.32v8.42c0,17.69-5.9,33.06-24,40.85l26.1,41.26v8.43Zm-70.74-109.7v29.9a266.16,266.16,0,0,0,33.05,1.9c33.69,0,34.32-5.9,34.32-19.16,0-7.58-.21-14.53-27.79-14.53C1160.25,280.84,1144.25,281.47,1130.35,282.73Z"
/> />
<path <path fill="#ff1d25" d="M1426,251.36v8.43l-62.75,132.64h-37.89l-62.74-132.64v-8.43h34.1l47.58,107.38,47.59-107.38Z" />
fill="#ff1d25"
d="M1426,251.36v8.43l-62.75,132.64h-37.89l-62.74-132.64v-8.43h34.1l47.58,107.38,47.59-107.38Z"
/>
<path fill="#ff1d25" d="M1496.49,251.36V392.43h-37.9V251.36Z" /> <path fill="#ff1d25" d="M1496.49,251.36V392.43h-37.9V251.36Z" />
<path <path
fill="#ff1d25" fill="#ff1d25"
d="M1534.39,316.42c0-38.11,16.63-69.27,76.22-69.27h7.57a218.19,218.19,0,0,1,54.32,6.95v34.32c-19.37-5.69-41-7.79-55.37-7.79-44,0-44,17.26-44,41.26s0,41.48,44,41.48a212.15,212.15,0,0,0,55.37-8V389.9a228.46,228.46,0,0,1-54.32,6.74h-7.57c-59.59,0-76.22-31.16-76.22-69.27Z" d="M1534.39,316.42c0-38.11,16.63-69.27,76.22-69.27h7.57a218.19,218.19,0,0,1,54.32,6.95v34.32c-19.37-5.69-41-7.79-55.37-7.79-44,0-44,17.26-44,41.26s0,41.48,44,41.48a212.15,212.15,0,0,0,55.37-8V389.9a228.46,228.46,0,0,1-54.32,6.74h-7.57c-59.59,0-76.22-31.16-76.22-69.27Z"
/> />
<path <path fill="#ff1d25" d="M1841.15,285.05h-97.06V306.1h76v33.69h-76v18.95h97.06v33.69h-135V251.36h135Z" />
fill="#ff1d25" <polygon fill="currentColor" points="1458.66 108.93 1458.66 83.93 1565.16 96.43 1671.66 108.93 1565.16 121.43 1458.66 133.93 1458.66 108.93" />
d="M1841.15,285.05h-97.06V306.1h76v33.69h-76v18.95h97.06v33.69h-135V251.36h135Z"
/>
<polygon
fill="currentColor"
points="1458.66 108.93 1458.66 83.93 1565.16 96.43 1671.66 108.93 1565.16 121.43 1458.66 133.93 1458.66 108.93"
/>
</svg> </svg>
{:else if layout === 'narrow'} {:else if layout === "narrow"}
<svg class={$$restProps['class']} {...$$restProps} viewBox="0 0 1920 1920"> <svg class={$$restProps["class"]} {...$$restProps} viewBox="0 0 1920 1920">
<g> <g>
<path <path
fill="#ff1d25" fill="#ff1d25"

View File

@@ -1,9 +1,9 @@
<script lang="ts"> <script lang="ts">
import { twMerge } from 'tailwind-merge'; import { twMerge } from "tailwind-merge";
</script> </script>
<svg <svg
class={twMerge('h-full', $$restProps['class'])} class={twMerge("h-full", $$restProps["class"])}
{...$$restProps} {...$$restProps}
fill="currentColor" fill="currentColor"
version="1.1" version="1.1"

View File

@@ -1,9 +1,9 @@
<script lang="ts"> <script lang="ts">
import { twMerge } from 'tailwind-merge'; import { twMerge } from "tailwind-merge";
</script> </script>
<svg <svg
class={twMerge('h-full', $$restProps['class'])} class={twMerge("h-full", $$restProps["class"])}
{...$$restProps} {...$$restProps}
fill="currentColor" fill="currentColor"
version="1.1" version="1.1"

View File

@@ -1,9 +1,9 @@
<script lang="ts"> <script lang="ts">
import { twMerge } from 'tailwind-merge'; import { twMerge } from "tailwind-merge";
</script> </script>
<svg <svg
class={twMerge('h-full', $$restProps['class'])} class={twMerge("h-full", $$restProps["class"])}
{...$$restProps} {...$$restProps}
fill="currentColor" fill="currentColor"
version="1.1" version="1.1"

View File

@@ -1,9 +1,9 @@
<script lang="ts"> <script lang="ts">
import { twMerge } from 'tailwind-merge'; import { twMerge } from "tailwind-merge";
</script> </script>
<svg <svg
class={twMerge('h-full', $$restProps['class'])} class={twMerge("h-full", $$restProps["class"])}
{...$$restProps} {...$$restProps}
fill="currentColor" fill="currentColor"
version="1.1" version="1.1"

View File

@@ -1,15 +1,8 @@
<script lang="ts"> <script lang="ts">
import { twMerge } from 'tailwind-merge'; import { twMerge } from "tailwind-merge";
export let href: string; export let href: string;
</script> </script>
<a <a {...$$restProps} {href} class={twMerge("font-medium transition-colors hover:text-accent hover:underline", $$restProps["class"])}>
{...$$restProps}
{href}
class={twMerge(
'font-medium transition-colors hover:text-accent hover:underline',
$$restProps['class']
)}
>
<slot /> <slot />
</a> </a>

View File

@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { scale } from 'svelte/transition'; import { scale } from "svelte/transition";
import { twMerge } from 'tailwind-merge'; import { twMerge } from "tailwind-merge";
export const toggle = () => { export const toggle = () => {
if (visible) { if (visible) {
@@ -38,8 +38,8 @@
transition:scale={{ duration: 200 }} transition:scale={{ duration: 200 }}
class={twMerge( class={twMerge(
`fixed inset-0 z-40 flex max-h-[calc(100vh-16rem)] flex-col rounded-md border-2 border-contrast-100 bg-primary-100 p-6 text-contrast-900 lg:w-3/4`, `fixed inset-0 z-40 flex max-h-[calc(100vh-16rem)] flex-col rounded-md border-2 border-contrast-100 bg-primary-100 p-6 text-contrast-900 lg:w-3/4`,
$$restProps['class'], $$restProps["class"],
visible ? '' : 'hidden' visible ? "" : "hidden"
)} )}
{...$$restProps} {...$$restProps}
> >

View File

@@ -8,9 +8,7 @@
</script> </script>
{#if $toasts.length >= 1} {#if $toasts.length >= 1}
<div <div class="fixed bottom-0 right-0 z-50 flex w-full flex-col gap-2 p-4 text-white sm:w-96">
class="fixed bottom-0 right-0 z-50 flex w-full flex-col gap-2 p-4 text-white sm:w-96"
>
{#each $toasts as toastItem} {#each $toasts as toastItem}
<div <div
class:bg-red-500={toastItem.type === "error"} class:bg-red-500={toastItem.type === "error"}
@@ -42,24 +40,9 @@
{toastItem.text} {toastItem.text}
</p> </p>
<button <button on:click={() => toast.dismiss(toastItem.id)} class="shrink-0" aria-label="dismiss">
on:click={() => toast.dismiss(toastItem.id)} <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6">
class="shrink-0" <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
aria-label="dismiss"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M6 18L18 6M6 6l12 12"
/>
</svg> </svg>
</button> </button>
</div> </div>

View File

@@ -1,23 +1,15 @@
import { writable } from 'svelte/store'; import { writable } from "svelte/store";
export const toasts = writable<Toast[]>([]); export const toasts = writable<Toast[]>([]);
type Toast = { type Toast = {
id: string; id: string;
type: 'success' | 'error' | 'info' | 'warning'; type: "success" | "error" | "info" | "warning";
text: string; text: string;
}; };
function addToast( function addToast(text: string, type: "success" | "error" | "warning" | "info" = "info", dismissible: boolean) {
text: string, const id: string = `toast-${crypto.randomUUID ? crypto.randomUUID() : Math.floor(Date.now() * Math.random() * 100).toString()}`;
type: 'success' | 'error' | 'warning' | 'info' = 'info',
dismissible: boolean
) {
const id: string = `toast-${
crypto.randomUUID
? crypto.randomUUID()
: Math.floor(Date.now() * Math.random() * 100).toString()
}`;
toasts.update((all) => [ toasts.update((all) => [
...all, ...all,
@@ -36,11 +28,9 @@ function dismiss(id: string) {
export const toast = { export const toast = {
clear: () => toasts.set([]), clear: () => toasts.set([]),
error: (text: string | null, dismissible = true) => error: (text: string | null, dismissible = true) => addToast(text ?? "En feil oppstod", "error", dismissible),
addToast(text ?? 'En feil oppstod', 'error', dismissible), info: (text: string, dismissible = true) => addToast(text, "info", dismissible),
info: (text: string, dismissible = true) => addToast(text, 'info', dismissible), warning: (text: string, dismissible = true) => addToast(text, "warning", dismissible),
warning: (text: string, dismissible = true) => addToast(text, 'warning', dismissible), success: (text: string | null, dismissible = true) => addToast(text ?? "Suksess", "success", dismissible),
success: (text: string | null, dismissible = true) =>
addToast(text ?? 'Suksess', 'success', dismissible),
dismiss: dismiss dismiss: dismiss
}; };

View File

@@ -14,86 +14,74 @@ export class Routes {
url: "/", url: "/",
text: "Hjem", text: "Hjem",
icon: homeIcon, icon: homeIcon,
target: null, target: null
}; };
static bus: Route = { static bus: Route = {
url: "/bus", url: "/bus",
text: "Buss", text: "Buss",
icon: busIcon, icon: busIcon,
target: null, target: null
}; };
static taxi: Route = { static taxi: Route = {
url: "/taxi", url: "/taxi",
text: "Taxi", text: "Taxi",
icon: null, icon: null,
target: null, target: null
}; };
static accessibility: Route = { static accessibility: Route = {
url: "/accessibility", url: "/accessibility",
text: "Tilgjengelighetsfunksjoner", text: "Tilgjengelighetsfunksjoner",
icon: null, icon: null,
target: null, target: null
}; };
static contact: Route = { static contact: Route = {
url: "/contact", url: "/contact",
text: "Ta kontakt", text: "Ta kontakt",
icon: contactIcon, icon: contactIcon,
target: null, target: null
}; };
static facebook: Route = { static facebook: Route = {
url: "https://www.facebook.com/MinibusserviceSteneAS/", url: "https://www.facebook.com/MinibusserviceSteneAS/",
text: "Facebook", text: "Facebook",
icon: null, icon: null,
target: "_blank", target: "_blank"
}; };
static email: Route = { static email: Route = {
url: "mailto:minibusstur@hotmail.com", url: "mailto:minibusstur@hotmail.com",
text: "E-post", text: "E-post",
icon: null, icon: null,
target: null, target: null
}; };
static phone: Route = { static phone: Route = {
url: "tel:45256161", url: "tel:45256161",
text: "Telefon", text: "Telefon",
icon: null, icon: null,
target: null, target: null
}; };
static topbarRoutes: Route[] = [Routes.home, Routes.bus, Routes.contact]; static topbarRoutes: Route[] = [Routes.home, Routes.bus, Routes.contact];
static sidebarRoutes: Route[] = [ static sidebarRoutes: Route[] = [Routes.home, Routes.bus, Routes.taxi, Routes.accessibility, Routes.contact];
Routes.home,
Routes.bus,
Routes.taxi,
Routes.accessibility,
Routes.contact,
];
static footerRoutes: { text: string; routes: Route[] }[] = [ static footerRoutes: { text: string; routes: Route[] }[] = [
{ {
text: "HJELP", text: "HJELP",
routes: [Routes.contact], routes: [Routes.contact]
}, },
{ {
text: "SIDER", text: "SIDER",
routes: [ routes: [Routes.home, Routes.bus, Routes.taxi, Routes.accessibility, Routes.contact]
Routes.home,
Routes.bus,
Routes.taxi,
Routes.accessibility,
Routes.contact,
],
}, },
{ {
text: "MINIBUSSERVICE", text: "MINIBUSSERVICE",
routes: [Routes.facebook, Routes.email, Routes.phone], routes: [Routes.facebook, Routes.email, Routes.phone]
}, }
]; ];
} }

View File

@@ -6,10 +6,7 @@ function createThemeToggler() {
if (savedValue) { if (savedValue) {
defaultValue = JSON.parse(savedValue); defaultValue = JSON.parse(savedValue);
} else if ( } else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
) {
defaultValue = true; defaultValue = true;
} }
@@ -32,7 +29,7 @@ function createThemeToggler() {
} }
localStorage.setItem("dark_theme", JSON.stringify(value)); localStorage.setItem("dark_theme", JSON.stringify(value));
}, }
}; };
} }

View File

@@ -2,7 +2,7 @@ import { mount } from "svelte";
import App from "./App.svelte"; import App from "./App.svelte";
const app = mount(App, { const app = mount(App, {
target: document.getElementById("app")!, target: document.getElementById("app")!
}); });
export default app; export default app;

View File

@@ -4,34 +4,21 @@
import threeRampsOpen from "../assets/images/three_ramps_open.jpg"; import threeRampsOpen from "../assets/images/three_ramps_open.jpg";
import Carousel from "../lib/components/carousel/Carousel.svelte"; import Carousel from "../lib/components/carousel/Carousel.svelte";
let rampCarouselItems: string[] = [ let rampCarouselItems: string[] = [singleRampLeftClosed, singleRampRightClosed, threeRampsOpen];
singleRampLeftClosed,
singleRampRightClosed,
threeRampsOpen,
];
</script> </script>
<h1 class="text-xl font-semibold md:text-2xl">Tilgjengelighetsfunksjoner</h1> <h1 class="text-xl font-semibold md:text-2xl">Tilgjengelighetsfunksjoner</h1>
<section <section class="mt-4 justify-between gap-5 rounded-md bg-primary-300 p-4 shadow-inner md:flex">
class="mt-4 justify-between gap-5 rounded-md bg-primary-300 p-4 shadow-inner md:flex"
>
<div> <div>
<h2 class="grow text-lg font-semibold md:text-xl"> <h2 class="grow text-lg font-semibold md:text-xl">Sitter du i rullestol?</h2>
Sitter du i rullestol?
</h2>
<p class="md:text-lg"> <p class="md:text-lg">
Vi har flere busser med rullestolstøtte, med kapasitet opp til 2 Vi har flere busser med rullestolstøtte, med kapasitet opp til 2 rullestoler per buss.
rullestoler per buss.
<br />Total kapasitet er 5 rullestilbrukere fordelt på 3 busser <br />Total kapasitet er 5 rullestilbrukere fordelt på 3 busser
</p> </p>
</div> </div>
<div class="md:w-96"> <div class="md:w-96">
<Carousel <Carousel items={rampCarouselItems} buttonClass="bg-primary-200" let:item>
items={rampCarouselItems}
buttonClass="bg-primary-200"
let:item
>
<div class="h-full w-96 overflow-hidden shadow-sm"> <div class="h-full w-96 overflow-hidden shadow-sm">
<img class="card w-full object-cover" src={item} alt="" /> <img class="card w-full object-cover" src={item} alt="" />
</div> </div>

View File

@@ -9,43 +9,23 @@
import tourBusSideLogo from "../assets/images/tour_bus_side_logo.jpg"; import tourBusSideLogo from "../assets/images/tour_bus_side_logo.jpg";
import Carousel from "../lib/components/carousel/Carousel.svelte"; import Carousel from "../lib/components/carousel/Carousel.svelte";
let minibusCarouselItems: string[] = [ let minibusCarouselItems: string[] = [threeBusses, twoBusses, fiveBusses, singleRampLeftClosed, threeRampsOpen];
threeBusses,
twoBusses,
fiveBusses,
singleRampLeftClosed,
threeRampsOpen,
];
let tourBusCarouselItems: string[] = [ let tourBusCarouselItems: string[] = [twoTourBuses, tourBusSide, tourBusSideLogo];
twoTourBuses,
tourBusSide,
tourBusSideLogo,
];
</script> </script>
<h1 class="text-xl font-semibold md:text-2xl">Buss</h1> <h1 class="text-xl font-semibold md:text-2xl">Buss</h1>
<section <section id="minibus" class="mt-4 justify-between gap-5 rounded-md bg-primary-300 p-4 shadow-inner md:flex">
id="minibus"
class="mt-4 justify-between gap-5 rounded-md bg-primary-300 p-4 shadow-inner md:flex"
>
<div> <div>
<h2 class="grow text-lg font-semibold md:text-xl">Minibusser</h2> <h2 class="grow text-lg font-semibold md:text-xl">Minibusser</h2>
<p class="md:text-lg"> <p class="md:text-lg">
Vi har idag fire minibusser, to Mercedes Sprinter og to Ford Vi har idag fire minibusser, to Mercedes Sprinter og to Ford Transit. Vi har også en fullelektrisk Mercedes EQV og en Mitsubishi Outlander.
Transit. Vi har også en fullelektrisk Mercedes EQV og en Mitsubishi <br />Vi finner løsninger for grupper fra 5 - 32 passasjerer med støtte for inntil 3 rullestolbrukere samtidig
Outlander.
<br />Vi finner løsninger for grupper fra 5 - 32 passasjerer med
støtte for inntil 3 rullestolbrukere samtidig
</p> </p>
</div> </div>
<div class="md:w-96"> <div class="md:w-96">
<Carousel <Carousel items={minibusCarouselItems} buttonClass="bg-primary-200" let:item>
items={minibusCarouselItems}
buttonClass="bg-primary-200"
let:item
>
<div class="w-96 overflow-hidden shadow-sm"> <div class="w-96 overflow-hidden shadow-sm">
<img class="card w-full object-cover" src={item} alt="" /> <img class="card w-full object-cover" src={item} alt="" />
</div> </div>
@@ -53,26 +33,17 @@
</div> </div>
</section> </section>
<section <section id="tour" class="mt-12 justify-between gap-5 rounded-md bg-primary-300 p-4 shadow-inner md:flex">
id="tour"
class="mt-12 justify-between gap-5 rounded-md bg-primary-300 p-4 shadow-inner md:flex"
>
<div> <div>
<h2 class="grow text-lg font-semibold md:text-xl">Turbusser</h2> <h2 class="grow text-lg font-semibold md:text-xl">Turbusser</h2>
<p class="md:text-lg"> <p class="md:text-lg">
Vi er medeier i Storfjord Turbuss AS som har tre turbusser. Vi er medeier i Storfjord Turbuss AS som har tre turbusser.
<br />Storfjord Turbuss AS ble etablert i 2018, og vi utfører <br />Storfjord Turbuss AS ble etablert i 2018, og vi utfører turkjøring og lager pakkeløsninger etter dine ønsker og behov.
turkjøring og lager pakkeløsninger etter dine ønsker og behov. <br />Vår målsetning er å alltid være det naturlige førstevalget av transportør
<br />Vår målsetning er å alltid være det naturlige førstevalget av
transportør
</p> </p>
</div> </div>
<div class="md:w-96"> <div class="md:w-96">
<Carousel <Carousel items={tourBusCarouselItems} buttonClass="bg-primary-200" let:item>
items={tourBusCarouselItems}
buttonClass="bg-primary-200"
let:item
>
<div class="w-96 overflow-hidden shadow-sm"> <div class="w-96 overflow-hidden shadow-sm">
<img class="card w-full object-cover" src={item} alt="" /> <img class="card w-full object-cover" src={item} alt="" />
</div> </div>

View File

@@ -22,79 +22,59 @@
image: threeBusses, image: threeBusses,
header: "Minibusstransport", header: "Minibusstransport",
text: "Vi har 4 minibusser i ulike størrelser", text: "Vi har 4 minibusser i ulike størrelser",
url: `${Routes.bus.url}#minibus`, url: `${Routes.bus.url}#minibus`
}, },
{ {
image: taxis, image: taxis,
header: "Taxikjøring", header: "Taxikjøring",
text: "Vi kjører taxi med kapasitet opptil 8 personer", text: "Vi kjører taxi med kapasitet opptil 8 personer",
url: `${Routes.taxi.url}#person`, url: `${Routes.taxi.url}#person`
}, },
{ {
image: wheelchairRamps, image: wheelchairRamps,
header: "Rullestoltransport", header: "Rullestoltransport",
text: "Fire av våre biler er rullestoltilpasset med plass til inntil 3 rullestoler", text: "Fire av våre biler er rullestoltilpasset med plass til inntil 3 rullestoler",
url: `${Routes.accessibility.url}`, url: `${Routes.accessibility.url}`
}, },
{ {
image: twoTourBusses, image: twoTourBusses,
header: "Turbuss", header: "Turbuss",
text: "Vi er medeier i Storfjord Turbuss AS, som har tre moderne turbusser for inntil 50 personer", text: "Vi er medeier i Storfjord Turbuss AS, som har tre moderne turbusser for inntil 50 personer",
url: `${Routes.bus.url}#tour`, url: `${Routes.bus.url}#tour`
}, },
{ {
image: van, image: van,
header: "Pakketaxi", header: "Pakketaxi",
text: "Vi har tilbud om pakketaxi. Både småpakker og volumkrevende gods kan transporteres", text: "Vi har tilbud om pakketaxi. Både småpakker og volumkrevende gods kan transporteres",
url: `${Routes.taxi.url}#package`, url: `${Routes.taxi.url}#package`
}, }
]; ];
</script> </script>
<div class="flex gap-8"> <div class="flex gap-8">
<div class="overflow-hidden"> <div class="overflow-hidden">
<div> <div>
<img <img src={header_image} class="rounded-md border-2 border-contrast-100" alt="Minibusses lined up in a row" />
src={header_image}
class="rounded-md border-2 border-contrast-100"
alt="Minibusses lined up in a row"
/>
<h1 class="mt-4 text-xl font-semibold md:text-2xl"> <h1 class="mt-4 text-xl font-semibold md:text-2xl">
Med komfort og sikkerhet i førersetet<br />Bli med på en trygg Med komfort og sikkerhet i førersetet<br />Bli med på en trygg og behagelig tur
og behagelig tur
</h1> </h1>
<p class="mt-2 font-medium opacity-70 md:text-lg"> <p class="mt-2 font-medium opacity-70 md:text-lg">
Minibusservice Stene AS driver personbefordring med taxi, Minibusservice Stene AS driver personbefordring med taxi, minibuss og busser.
minibuss og busser. <br />Vi har lang erfaring og finner gode løsninger for kundene våre.
<br />Vi har lang erfaring og finner gode løsninger for kundene <br />Kontraktskjøring for helseforetak, busselskap og kommune utgjør størsteparten av oppdragene våre, men vi tilbyr også turer for privatpersoner, bedrifter og
våre. turister.
<br />Kontraktskjøring for helseforetak, busselskap og kommune <br />Vi er godkjent lærebedrift og setter kunden og miljøet i fokus. Vi har både elektriske, hybride og dieselkjøretøy i flåten
utgjør størsteparten av oppdragene våre, men vi tilbyr også
turer for privatpersoner, bedrifter og turister.
<br />Vi er godkjent lærebedrift og setter kunden og miljøet i
fokus. Vi har både elektriske, hybride og dieselkjøretøy i
flåten
</p> </p>
</div> </div>
<div class="mt-12"> <div class="mt-12">
<h1 class="text-xl font-semibold md:text-2xl">Våre tjenester</h1> <h1 class="text-xl font-semibold md:text-2xl">Våre tjenester</h1>
<Carousel <Carousel class="mt-2 rounded-md border-2 border-contrast-100 bg-primary-300 p-4 shadow-inner" items={carouselItems} let:item>
class="mt-2 rounded-md border-2 border-contrast-100 bg-primary-300 p-4 shadow-inner" <div class="card flex h-full w-64 flex-col overflow-hidden border-contrast-100 shadow-sm transition-transform">
items={carouselItems}
let:item
>
<div
class="card flex h-full w-64 flex-col overflow-hidden border-contrast-100 shadow-sm transition-transform"
>
{#if item.image} {#if item.image}
<img <img class="h-44 w-full border-b-2 border-contrast-100 object-cover" src={item.image} alt="" />
class="h-44 w-full border-b-2 border-contrast-100 object-cover"
src={item.image}
alt=""
/>
{/if} {/if}
<div class="flex grow flex-col p-4"> <div class="flex grow flex-col p-4">
<h3 class="font-semibold"> <h3 class="font-semibold">
@@ -103,10 +83,7 @@
<p class="grow whitespace-normal"> <p class="grow whitespace-normal">
{item.text} {item.text}
</p> </p>
<Link <Link class="hi mt-2 w-fit font-semibold" href={item.url}>Les mer...</Link>
class="hi mt-2 w-fit font-semibold"
href={item.url}>Les mer...</Link
>
</div> </div>
</div> </div>
</Carousel> </Carousel>

View File

@@ -9,25 +9,17 @@
<h1 class="text-xl font-semibold md:text-2xl">Taxi</h1> <h1 class="text-xl font-semibold md:text-2xl">Taxi</h1>
<section <section id="person" class="mt-4 justify-between gap-5 rounded-md bg-primary-300 p-4 shadow-inner md:flex">
id="person"
class="mt-4 justify-between gap-5 rounded-md bg-primary-300 p-4 shadow-inner md:flex"
>
<div> <div>
<h2 class="grow text-lg font-semibold md:text-xl">Persontaxi</h2> <h2 class="grow text-lg font-semibold md:text-xl">Persontaxi</h2>
<p class="md:text-lg"> <p class="md:text-lg">
Vi har taxier som dekker de fleste behov. Vi har taxier som dekker de fleste behov.
<br />Rullestoltransport, firehjulstrekk og helelektrisk bil er noen <br />Rullestoltransport, firehjulstrekk og helelektrisk bil er noen av tilbudene våre.
av tilbudene våre.
<br />Taxiene våre kan ta opp til 8 passasjerer <br />Taxiene våre kan ta opp til 8 passasjerer
</p> </p>
</div> </div>
<div class="md:w-96"> <div class="md:w-96">
<Carousel <Carousel items={taxiCarouselItems} buttonClass="bg-primary-200" let:item>
items={taxiCarouselItems}
buttonClass="bg-primary-200"
let:item
>
<div class="card w-96 overflow-hidden shadow-sm"> <div class="card w-96 overflow-hidden shadow-sm">
<img class="w-full object-cover" src={item} alt="" /> <img class="w-full object-cover" src={item} alt="" />
</div> </div>
@@ -35,23 +27,13 @@
</div> </div>
</section> </section>
<section <section id="package" class="mt-4 justify-between gap-5 rounded-md bg-primary-300 p-4 shadow-inner md:flex">
id="package"
class="mt-4 justify-between gap-5 rounded-md bg-primary-300 p-4 shadow-inner md:flex"
>
<div> <div>
<h2 class="grow text-lg font-semibold md:text-xl">Pakketaxi</h2> <h2 class="grow text-lg font-semibold md:text-xl">Pakketaxi</h2>
<p class="md:text-lg"> <p class="md:text-lg">Vi har tilbud om pakketaxi. Både småpakker og volumkrevende gods kan transporteres</p>
Vi har tilbud om pakketaxi. Både småpakker og volumkrevende gods kan
transporteres
</p>
</div> </div>
<div class="md:w-96"> <div class="md:w-96">
<Carousel <Carousel items={packageTaxiCarouselItems} buttonClass="bg-primary-200" let:item>
items={packageTaxiCarouselItems}
buttonClass="bg-primary-200"
let:item
>
<div class="card w-96 overflow-hidden"> <div class="card w-96 overflow-hidden">
<img class="w-full object-cover" src={item} alt="" /> <img class="w-full object-cover" src={item} alt="" />
</div> </div>

View File

@@ -1,2 +1,2 @@
/** @type {import("@sveltejs/vite-plugin-svelte").SvelteConfig} */ /** @type {import("@sveltejs/vite-plugin-svelte").SvelteConfig} */
export default {} export default {};

View File

@@ -1,7 +1,4 @@
{ {
"files": [], "files": [],
"references": [ "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
} }

View File

@@ -4,5 +4,5 @@ import tailwindcss from "@tailwindcss/vite";
// https://vite.dev/config/ // https://vite.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [svelte(), tailwindcss()], plugins: [svelte(), tailwindcss()]
}); });