first commit
This commit is contained in:
commit
e687b4437b
418 files changed
+33577
No files matched your search
@@ -0,0 +1,197 @@
|
||||
<script lang="ts">
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
CardContent,
|
||||
CardFooter,
|
||||
} from '@/components/ui/card';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
|
||||
import { AlertCircle, Building2, Phone, Mail, Clock } from 'lucide-svelte';
|
||||
import * as Select from '@/components/ui/select/index.js';
|
||||
|
||||
interface ContactFormProps {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
subject: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
let contactForm: ContactFormProps = {
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
subject: 'Web Development',
|
||||
message: '',
|
||||
};
|
||||
|
||||
let invalidInputForm = false;
|
||||
|
||||
function handleSubmit(event: SubmitEvent) {
|
||||
event.preventDefault();
|
||||
const { firstName, lastName, email, subject, message } = contactForm;
|
||||
console.log(contactForm);
|
||||
|
||||
const mailToLink = `mailto:leomirandadev@gmail.com?subject=${subject}&body=Hello I am ${firstName} ${lastName}, my Email is ${email}. %0D%0A${message}`;
|
||||
window.location.href = mailToLink;
|
||||
}
|
||||
|
||||
const subjects = [
|
||||
{ value: 'Web Development', label: 'Web Development' },
|
||||
{ value: 'Mobile Development', label: 'Mobile Development' },
|
||||
{ value: 'Figma Design', label: 'Figma Design' },
|
||||
{ value: 'REST API', label: 'REST API' },
|
||||
{ value: 'FullStack Project', label: 'FullStack Project' },
|
||||
];
|
||||
|
||||
$: triggerContent =
|
||||
subjects.find((s) => s.value === contactForm.subject)?.label ??
|
||||
'Select a subject';
|
||||
</script>
|
||||
|
||||
<section id="contact" class="container py-24 sm:py-32">
|
||||
<section class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<h2 class="text-lg text-primary mb-2 tracking-wider">
|
||||
Contact
|
||||
</h2>
|
||||
<h2 class="text-3xl md:text-4xl font-bold">Connect With Us</h2>
|
||||
</div>
|
||||
<p class="mb-8 text-muted-foreground lg:w-5/6">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Voluptatum ipsam sint enim exercitationem ex autem corrupti quas
|
||||
tenetur
|
||||
</p>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
<div class="flex gap-2 mb-1">
|
||||
<Building2 />
|
||||
<div class="font-bold">Find Us</div>
|
||||
</div>
|
||||
<div>742 Evergreen Terrace, Springfield, IL 62704</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="flex gap-2 mb-1">
|
||||
<Phone />
|
||||
<div class="font-bold">Call Us</div>
|
||||
</div>
|
||||
<div>+1 (619) 123-4567</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="flex gap-2 mb-1">
|
||||
<Mail />
|
||||
<div class="font-bold">Mail Us</div>
|
||||
</div>
|
||||
<div>leomirandadev@gmail.com</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="flex gap-2 mb-1">
|
||||
<Clock />
|
||||
<div class="font-bold">Visit Us</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>Monday - Friday</div>
|
||||
<div>8AM - 4PM</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Form -->
|
||||
<Card class="bg-muted/60 dark:bg-card">
|
||||
<CardHeader class="text-primary text-2xl" />
|
||||
<CardContent>
|
||||
<form on:submit={handleSubmit} class="grid gap-4">
|
||||
<div class="flex flex-col md:flex-row gap-8">
|
||||
<div class="flex flex-col w-full gap-1.5">
|
||||
<Label for="firstName">First Name</Label>
|
||||
<Input
|
||||
id="firstName"
|
||||
type="text"
|
||||
placeholder="Leopoldo"
|
||||
value={contactForm.firstName}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col w-full gap-1.5">
|
||||
<Label for="lastName">Last Name</Label>
|
||||
<Input
|
||||
id="lastName"
|
||||
type="text"
|
||||
placeholder="Miranda"
|
||||
value={contactForm.lastName}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<Label for="contactEmail">Email</Label>
|
||||
<Input
|
||||
id="contactEmail"
|
||||
type="email"
|
||||
placeholder="leomirandadev@gmail.com"
|
||||
value={contactForm.email}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<Label for="contactSubject">Subject</Label>
|
||||
<Select.Root
|
||||
type="single"
|
||||
bind:value={contactForm.subject}
|
||||
>
|
||||
<Select.Trigger id="contactSubject" class="w-full">
|
||||
{triggerContent}
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
<Select.Group>
|
||||
{#each subjects as subject}
|
||||
<Select.Item
|
||||
value={subject.value}
|
||||
label={subject.label}
|
||||
>
|
||||
{subject.label}
|
||||
</Select.Item>
|
||||
{/each}
|
||||
</Select.Group>
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<Label for="contactMessage">Message</Label>
|
||||
<Textarea
|
||||
id="contactMessage"
|
||||
placeholder="Your message..."
|
||||
rows={5}
|
||||
bind:value={contactForm.message}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if invalidInputForm}
|
||||
<Alert variant="destructive">
|
||||
<AlertCircle class="w-4 h-4" />
|
||||
<AlertTitle>Error</AlertTitle>
|
||||
<AlertDescription>
|
||||
There is an error in the form. Please check your
|
||||
input.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
{/if}
|
||||
|
||||
<Button class="mt-4">Send message</Button>
|
||||
</form>
|
||||
</CardContent>
|
||||
<CardFooter />
|
||||
</Card>
|
||||
</section>
|
||||
</section>
|
||||
@@ -0,0 +1,76 @@
|
||||
<script lang="ts">
|
||||
interface FAQProps {
|
||||
question: string;
|
||||
answer: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from '@/components/ui/accordion';
|
||||
|
||||
const FAQList: FAQProps[] = [
|
||||
{
|
||||
question: 'Is this template free?',
|
||||
answer: 'Yes. It is a free Shadcn/Svelte template.',
|
||||
value: 'item-1',
|
||||
},
|
||||
{
|
||||
question:
|
||||
'Duis aute irure dolor in reprehenderit in voluptate velit?',
|
||||
answer: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sint labore quidem quam consectetur sapiente, iste rerum reiciendis animi nihil nostrum sit quo, modi quod.',
|
||||
value: 'item-2',
|
||||
},
|
||||
{
|
||||
question:
|
||||
'Lorem ipsum dolor sit amet Consectetur natus dolor minus quibusdam?',
|
||||
answer: 'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Labore qui nostrum reiciendis veritatis.',
|
||||
value: 'item-3',
|
||||
},
|
||||
{
|
||||
question: 'Excepteur sint occaecat cupidata non proident sunt?',
|
||||
answer: 'Lorem ipsum dolor sit amet consectetur, adipisicing elit.',
|
||||
value: 'item-4',
|
||||
},
|
||||
{
|
||||
question:
|
||||
'Enim ad minim veniam, quis nostrud exercitation ullamco laboris?',
|
||||
answer: 'consectetur adipisicing elit. Sint labore.',
|
||||
value: 'item-5',
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<section id="faq" class="container md:w-175 py-24 sm:py-32">
|
||||
<div class="text-center mb-8">
|
||||
<h2 class="text-lg text-primary text-center mb-2 tracking-wider">
|
||||
FAQS
|
||||
</h2>
|
||||
<h2 class="text-3xl md:text-4xl text-center font-bold">
|
||||
Common Questions
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<Accordion type="single" class="w-full">
|
||||
{#each FAQList as { question, answer, value }}
|
||||
<AccordionItem {value}>
|
||||
<AccordionTrigger class="text-left">
|
||||
{question}
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
{answer}
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
{/each}
|
||||
</Accordion>
|
||||
|
||||
<h3 class="font-medium mt-4">
|
||||
Still have questions?
|
||||
<a href="#contact" class="text-muted-foreground">
|
||||
<span class="underline">Contact us</span>
|
||||
</a>
|
||||
</h3>
|
||||
</section>
|
||||
@@ -0,0 +1,123 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@/components/ui/card';
|
||||
import {
|
||||
Paintbrush,
|
||||
MessageCircle,
|
||||
TabletSmartphone,
|
||||
BadgeCheck,
|
||||
Goal,
|
||||
PictureInPicture,
|
||||
MousePointerClick,
|
||||
Newspaper,
|
||||
} from 'lucide-svelte';
|
||||
|
||||
interface FeaturesProps {
|
||||
icon:
|
||||
| 'tabletSmartphone'
|
||||
| 'badgeCheck'
|
||||
| 'goal'
|
||||
| 'pictureInPicture'
|
||||
| 'paintbrush'
|
||||
| 'mousePointerClick'
|
||||
| 'messageCircle'
|
||||
| 'newspaper';
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
const featureList: FeaturesProps[] = [
|
||||
{
|
||||
icon: 'tabletSmartphone',
|
||||
title: 'Handy Freundlich',
|
||||
description:
|
||||
'Wir sind eine Website die auf Smartphones und Tablets gut lesbar, bedienbar und korrekt dargestellt wird, ohne dass Nutzer zoomen oder seitlich scrollen müssen.',
|
||||
},
|
||||
{
|
||||
icon: 'badgeCheck',
|
||||
title: 'Social Proof',
|
||||
description:
|
||||
'Bei ist die Möglicheit sich am Verhalten anderer zu orientieren unwahrscheinllich, du bist alleine und must lernen deine Entscheidungen selbstständig zu treffen.',
|
||||
},
|
||||
{
|
||||
icon: 'goal',
|
||||
title: 'Targeted Content',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet consectetur adipisicing elit. odio ea accusamus aperiam.',
|
||||
},
|
||||
{
|
||||
icon: 'pictureInPicture',
|
||||
title: 'Strong Visuals',
|
||||
description:
|
||||
'Lorem elit. A odio velit cum aliquam. Natus consectetur dolores, odio ea accusamus aperiam.',
|
||||
},
|
||||
{
|
||||
icon: 'mousePointerClick',
|
||||
title: 'Clear CTA',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet consectetur adipisicing. odio ea accusamus consectetur.',
|
||||
},
|
||||
{
|
||||
icon: 'newspaper',
|
||||
title: 'Clear Headline',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet consectetur adipisicing elit. A odio velit cum aliquam. Natus consectetur.',
|
||||
},
|
||||
];
|
||||
|
||||
const iconMap = {
|
||||
tabletSmartphone: TabletSmartphone,
|
||||
badgeCheck: BadgeCheck,
|
||||
goal: Goal,
|
||||
pictureInPicture: PictureInPicture,
|
||||
paintbrush: Paintbrush,
|
||||
mousePointerClick: MousePointerClick,
|
||||
messageCircle: MessageCircle,
|
||||
newspaper: Newspaper,
|
||||
};
|
||||
</script>
|
||||
|
||||
<section id="features" class="container py-24 sm:py-32">
|
||||
<h2 class="text-lg text-primary text-center mb-2 tracking-wider">
|
||||
Features
|
||||
</h2>
|
||||
|
||||
<h2 class="text-3xl md:text-4xl text-center font-bold mb-4">
|
||||
Was macht uns so besonderes
|
||||
</h2>
|
||||
|
||||
<h3 class="md:w-1/2 mx-auto text-xl text-center text-muted-foreground mb-8">
|
||||
Der Überlieferung nach ist das Spiel in der heutigen Form in der Zeit
|
||||
der napoleonischen Kriege in den Gefangenenlagern um Mantua entstanden.
|
||||
Damals verbrachten die miteinander verbündeten Franzosen und Italienern
|
||||
ihre Freizeit mit den in den dortigen Feldlagern festgehalenen Tirolern.
|
||||
Der Name entstand aus dem französischen Begriff va tout (letzter
|
||||
Trumpf).
|
||||
</h3>
|
||||
|
||||
<div class="grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{#each featureList as { icon, title, description }}
|
||||
<Card class="h-full bg-background border-0 shadow-none">
|
||||
<CardHeader class="flex justify-center items-center">
|
||||
<div
|
||||
class="bg-primary/20 p-2 rounded-full ring-8 ring-primary/10 mb-4"
|
||||
>
|
||||
<svelte:component
|
||||
this={iconMap[icon]}
|
||||
class="size-6 text-primary"
|
||||
/>
|
||||
</div>
|
||||
<CardTitle>{title}</CardTitle>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent class="text-muted-foreground text-center">
|
||||
{description}
|
||||
</CardContent>
|
||||
</Card>
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,108 @@
|
||||
<script lang="ts">
|
||||
import hubsch from '@/lib/assets/kings/square/hubsch.jpg';
|
||||
import { Separator } from '@/components/ui/separator';
|
||||
import WebWerkstatt from '@/components/my/WebWerkstatt.svelte';
|
||||
</script>
|
||||
|
||||
<footer id="footer" class="container py-24 pb-16 sm:py-32 sm:pb-24">
|
||||
<div class="p-10 bg-muted/50 dark:bg-card border rounded-2xl">
|
||||
<div
|
||||
class="grid grid-cols-2 md:grid-cols-4 xl:grid-cols-6 gap-x-12 gap-y-8"
|
||||
>
|
||||
<div class="col-span-full xl:col-span-2">
|
||||
<a href="/" class="flex font-bold items-center gap-2">
|
||||
<enhanced:img
|
||||
src={hubsch}
|
||||
alt="Kaiser Hubsch"
|
||||
class="max-w-8 aspect-square rounded-full border-3 dark:border border-lime-600 drop-shadow-2xl"
|
||||
/>
|
||||
<h3 class="text-2xl">FC Dotterbühel</h3>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<h3 class="font-bold text-lg">Kontakt</h3>
|
||||
<div>
|
||||
<a
|
||||
href="https://github.com"
|
||||
class="opacity-60 hover:opacity-100">Github</a
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="https://twitter.com"
|
||||
class="opacity-60 hover:opacity-100">Twitter</a
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="https://instagram.com"
|
||||
class="opacity-60 hover:opacity-100">Instagram</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<h3 class="font-bold text-lg">Platformen</h3>
|
||||
<div>
|
||||
<span class="opacity-60 hover:opacity-100 cursor-default"
|
||||
>iOS</span
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<span class="opacity-60 hover:opacity-100 cursor-default"
|
||||
>Android</span
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<span class="opacity-60 hover:opacity-100 cursor-default"
|
||||
>Web</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<h3 class="font-bold text-lg">Hilfe</h3>
|
||||
<div>
|
||||
<a href="#contact" class="opacity-60 hover:opacity-100"
|
||||
>Contact Us</a
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<a href="#faq" class="opacity-60 hover:opacity-100">FAQ</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="#contact" class="opacity-60 hover:opacity-100"
|
||||
>Feedback</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<h3 class="font-bold text-lg">Soziale Medien</h3>
|
||||
<div>
|
||||
<a
|
||||
href="https://twitch.tv"
|
||||
class="opacity-60 hover:opacity-100">Twitch</a
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="https://discord.com"
|
||||
class="opacity-60 hover:opacity-100">Discord</a
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="https://dribbble.com"
|
||||
class="opacity-60 hover:opacity-100">Dribbble</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Separator class="my-6" />
|
||||
|
||||
<WebWerkstatt />
|
||||
</div>
|
||||
</footer>
|
||||
@@ -0,0 +1,82 @@
|
||||
<script lang="ts">
|
||||
import { Link, page } from '@inertiajs/svelte';
|
||||
import { toUrl } from '@/lib/utils';
|
||||
import { dashboard, login, register } from '@/routes';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import burg from '@/lib/assets/img/burg.jpg';
|
||||
import SunIcon from '@lucide/svelte/icons/sun';
|
||||
import MoonIcon from '@lucide/svelte/icons/moon';
|
||||
import { toggleMode } from 'mode-watcher';
|
||||
|
||||
let {
|
||||
canRegister = true,
|
||||
}: {
|
||||
canRegister: boolean;
|
||||
} = $props();
|
||||
|
||||
const auth = $derived(page.props.auth);
|
||||
</script>
|
||||
|
||||
<div class="text-center space-y-8">
|
||||
<Badge variant="outline" class="text-sm py-2">
|
||||
<span class="mr-2 text-primary">
|
||||
<Badge>Neu</Badge>
|
||||
</span>
|
||||
<span>Für Android, Apple oder Desktop!</span>
|
||||
</Badge>
|
||||
|
||||
<div class="max-w-3xl mx-auto text-center text-5xl md:text-6xl font-bold">
|
||||
<h1>
|
||||
<span
|
||||
class="text-transparent bg-linear-to-r from-lime-600 to-primary bg-clip-text"
|
||||
>
|
||||
Ladinisch Watten
|
||||
</span>
|
||||
<br />FC Dotterbühel
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<p class="max-w-screen-sm mx-auto text-xl text-muted-foreground">
|
||||
Ladinisch Watten vom Handy, Tablet oder PC, mit deinen Freunden oder auf
|
||||
der offenen Platform, nach deinen Regeln, mit begleitenden Statistiken.
|
||||
</p>
|
||||
<nav class="flex items-center justify-center gap-4">
|
||||
{#if auth.user}
|
||||
<Link href={toUrl(dashboard())} as="button">Dashboard</Link>
|
||||
{:else}
|
||||
<Link href={toUrl(login())}>
|
||||
<Button>Anmelden</Button>
|
||||
</Link>
|
||||
{#if canRegister}
|
||||
<Link href={toUrl(register())}>
|
||||
<Button variant="outline">Registrieren</Button>
|
||||
</Link>
|
||||
{/if}
|
||||
{/if}
|
||||
<Button onclick={toggleMode} variant="outline" size="icon">
|
||||
<SunIcon
|
||||
class="h-[1.2rem] w-[1.2rem] scale-100 rotate-0 transition-all! dark:scale-0 dark:-rotate-90"
|
||||
/>
|
||||
<MoonIcon
|
||||
class="absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 transition-all! dark:scale-100 dark:rotate-0"
|
||||
/>
|
||||
<span class="sr-only">Toggle theme</span>
|
||||
</Button>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="relative group mt-14">
|
||||
<div
|
||||
class="absolute -top-6 right-12 w-[90%] h-12 lg:h-[80%] bg-primary/50 blur-3xl rounded-full img-shadow-animation"
|
||||
></div>
|
||||
|
||||
<enhanced:img
|
||||
class="w-full mx-auto rounded-xl"
|
||||
src={burg}
|
||||
alt="dashboard using shadcn-svelte"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="absolute bottom-0 left-0 w-full h-20 md:h-28 bg-linear-to-b from-background/0 via-background/50 to-background"
|
||||
></div>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
import hubsch from '@/lib/assets/kings/square/hubsch.jpg';
|
||||
</script>
|
||||
|
||||
<enhanced:img
|
||||
src={hubsch}
|
||||
alt="Kaiser Hubsch"
|
||||
class="max-w-40 md:max-w-50 aspect-square rounded-full border-3 dark:border border-lime-600 drop-shadow-2xl"
|
||||
/>
|
||||
@@ -0,0 +1,219 @@
|
||||
<script lang="ts">
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@/components/ui/card';
|
||||
import { Check } from 'lucide-svelte';
|
||||
|
||||
interface PlanProps {
|
||||
title: string;
|
||||
popular: boolean;
|
||||
price: number;
|
||||
description: string;
|
||||
buttonText: string;
|
||||
benefitList: string[];
|
||||
}
|
||||
|
||||
const plans: PlanProps[] = [
|
||||
{
|
||||
title: 'Free',
|
||||
popular: false,
|
||||
price: 0,
|
||||
description:
|
||||
'Lorem ipsum dolor sit, amet ipsum consectetur adipisicing elit.',
|
||||
buttonText: 'Start Free Trial',
|
||||
benefitList: [
|
||||
'1 team member',
|
||||
'1 GB storage',
|
||||
'Upto 2 pages',
|
||||
'Community support',
|
||||
'AI assistance',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Premium',
|
||||
popular: true,
|
||||
price: 45,
|
||||
description:
|
||||
'Lorem ipsum dolor sit, amet ipsum consectetur adipisicing elit.',
|
||||
buttonText: 'Get Started',
|
||||
benefitList: [
|
||||
'4 team member',
|
||||
'8 GB storage',
|
||||
'Upto 6 pages',
|
||||
'Priority support',
|
||||
'AI assistance',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Enterprise',
|
||||
popular: false,
|
||||
price: 120,
|
||||
description:
|
||||
'Lorem ipsum dolor sit, amet ipsum consectetur adipisicing elit.',
|
||||
buttonText: 'Contact Us',
|
||||
benefitList: [
|
||||
'10 team member',
|
||||
'20 GB storage',
|
||||
'Upto 10 pages',
|
||||
'Phone & email support',
|
||||
'AI assistance',
|
||||
],
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<section class="container py-16 sm:py-32">
|
||||
<h2 class="text-lg text-primary text-center mb-2 tracking-wider">
|
||||
Pricing
|
||||
</h2>
|
||||
|
||||
<h2 class="text-3xl md:text-4xl text-center font-bold mb-4">
|
||||
Get unlimited access
|
||||
</h2>
|
||||
|
||||
<h3
|
||||
class="md:w-1/2 mx-auto text-xl text-center text-muted-foreground pb-14"
|
||||
>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing reiciendis.
|
||||
</h3>
|
||||
|
||||
<!-- Mobile First Layout -->
|
||||
<div class="block lg:hidden space-y-6">
|
||||
{#each plans as { title, popular, price, description, buttonText, benefitList }}
|
||||
<div class="relative">
|
||||
<Card class={popular ? 'popular-mobile' : ''}>
|
||||
{#if popular}
|
||||
<div class="absolute -top-4 left-1/2 -translate-x-1/2">
|
||||
<span
|
||||
class="bg-primary text-primary-foreground text-xs sm:text-sm font-medium px-3 sm:px-4 py-1 rounded-full whitespace-nowrap"
|
||||
>
|
||||
Most Popular
|
||||
</span>
|
||||
</div>
|
||||
{/if}
|
||||
<CardHeader>
|
||||
<CardTitle class="pb-2 text-lg sm:text-xl">
|
||||
{title}
|
||||
</CardTitle>
|
||||
|
||||
<CardDescription class="pb-4 text-sm sm:text-base"
|
||||
>{description}</CardDescription
|
||||
>
|
||||
|
||||
<div>
|
||||
<span class="text-2xl sm:text-3xl font-bold"
|
||||
>${price}</span
|
||||
>
|
||||
<span
|
||||
class="text-muted-foreground text-sm sm:text-base"
|
||||
>
|
||||
/month</span
|
||||
>
|
||||
</div>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent>
|
||||
<div class="space-y-3 sm:space-y-4">
|
||||
{#each benefitList as benefit}
|
||||
<span
|
||||
class="flex items-center text-sm sm:text-base"
|
||||
>
|
||||
<Check
|
||||
class="text-primary mr-2 h-4 w-4 sm:h-5 sm:w-5"
|
||||
/>
|
||||
<span>{benefit}</span>
|
||||
</span>
|
||||
{/each}
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
<CardFooter>
|
||||
<Button
|
||||
variant={popular ? 'default' : 'secondary'}
|
||||
class="w-full"
|
||||
>
|
||||
{buttonText}
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<!-- Desktop Layout -->
|
||||
<div class="hidden lg:grid lg:grid-cols-3 gap-8 relative">
|
||||
{#each plans as { title, popular, price, description, buttonText, benefitList }}
|
||||
<div
|
||||
class="relative {popular
|
||||
? 'scale-110 hover:scale-112 z-10'
|
||||
: 'hover:scale-105'} transition-all duration-200"
|
||||
>
|
||||
<Card
|
||||
class={popular
|
||||
? 'popular-desktop'
|
||||
: 'hover:border-primary/50'}
|
||||
>
|
||||
{#if popular}
|
||||
<div class="absolute -top-4 left-1/2 -translate-x-1/2">
|
||||
<span
|
||||
class="bg-primary text-primary-foreground text-sm font-medium px-4 py-1 rounded-full whitespace-nowrap shadow-lg"
|
||||
>
|
||||
Most Popular
|
||||
</span>
|
||||
</div>
|
||||
{/if}
|
||||
<CardHeader>
|
||||
<CardTitle class="pb-2 text-lg sm:text-xl">
|
||||
{title}
|
||||
</CardTitle>
|
||||
|
||||
<CardDescription class="pb-4 text-sm sm:text-base"
|
||||
>{description}</CardDescription
|
||||
>
|
||||
|
||||
<div>
|
||||
<span class="text-2xl sm:text-3xl font-bold"
|
||||
>${price}</span
|
||||
>
|
||||
<span
|
||||
class="text-muted-foreground text-sm sm:text-base"
|
||||
>
|
||||
/month</span
|
||||
>
|
||||
</div>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent>
|
||||
<div class="space-y-3 sm:space-y-4">
|
||||
{#each benefitList as benefit}
|
||||
<span
|
||||
class="flex items-center text-sm sm:text-base"
|
||||
>
|
||||
<Check
|
||||
class="text-primary mr-2 h-4 w-4 sm:h-5 sm:w-5"
|
||||
/>
|
||||
<span>{benefit}</span>
|
||||
</span>
|
||||
{/each}
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
<CardFooter>
|
||||
<Button
|
||||
variant={popular ? 'default' : 'secondary'}
|
||||
class="w-full"
|
||||
>
|
||||
{buttonText}
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,146 @@
|
||||
<script lang="ts">
|
||||
import andi from '@/lib/assets/athleten/andi.png';
|
||||
import edgar from '@/lib/assets/athleten/edgar.png';
|
||||
import salam from '@/lib/assets/athleten/salam.png';
|
||||
import helli from '@/lib/assets/athleten/helli.png';
|
||||
import hechi from '@/lib/assets/athleten/hechi.png';
|
||||
import clemens from '@/lib/assets/athleten/clemens.png';
|
||||
import gerhard from '@/lib/assets/athleten/gerhard.png';
|
||||
import hubsch from '@/lib/assets/athleten/hubsch.png';
|
||||
import rudi from '@/lib/assets/athleten/rudi.png';
|
||||
import rene from '@/lib/assets/athleten/rene.png';
|
||||
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
CardFooter,
|
||||
} from '@/components/ui/card';
|
||||
|
||||
interface TeamProps {
|
||||
imageUrl: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
positions: string[];
|
||||
}
|
||||
|
||||
const teamList: TeamProps[] = [
|
||||
{
|
||||
imageUrl: andi,
|
||||
firstName: 'Andi',
|
||||
lastName: 'Tengler',
|
||||
positions: ['Präsident', 'Optimist', 'Wirt'],
|
||||
},
|
||||
{
|
||||
imageUrl: edgar,
|
||||
firstName: 'Prof.',
|
||||
lastName: 'Waffler',
|
||||
positions: ['Kassier', 'Wein Koordinator', 'Venezianer'],
|
||||
},
|
||||
{
|
||||
imageUrl: salam,
|
||||
firstName: 'Salam',
|
||||
lastName: '',
|
||||
positions: ['Pizzaiolo', 'Wattergott Theist', '2x König'],
|
||||
},
|
||||
{
|
||||
imageUrl: helli,
|
||||
firstName: 'Helli',
|
||||
lastName: 'Cool',
|
||||
positions: ['Aufsteiger', 'Musiker', 'Blues Knacker Fan'],
|
||||
},
|
||||
{
|
||||
imageUrl: gerhard,
|
||||
firstName: 'Gerhard',
|
||||
lastName: '',
|
||||
positions: ['Risikomanagment', '8x König'],
|
||||
},
|
||||
{
|
||||
imageUrl: hechi,
|
||||
firstName: 'Hechi',
|
||||
lastName: 'THahn',
|
||||
positions: ['Schriftführer', 'Recordhalter', 'Musiker', '2x König'],
|
||||
},
|
||||
{
|
||||
imageUrl: clemens,
|
||||
firstName: 'Celemens',
|
||||
lastName: '',
|
||||
positions: ['Vorstand Regeln', '2x König'],
|
||||
},
|
||||
{
|
||||
imageUrl: hubsch,
|
||||
firstName: 'Hubsch',
|
||||
lastName: '',
|
||||
positions: ['Risikospieler', 'Wattergott Agnostiker', '3x König'],
|
||||
},
|
||||
{
|
||||
imageUrl: rudi,
|
||||
firstName: 'Rudi',
|
||||
lastName: '',
|
||||
positions: ['Gastspieler', 'Gerngesehen'],
|
||||
},
|
||||
{
|
||||
imageUrl: rene,
|
||||
firstName: 'René',
|
||||
lastName: '',
|
||||
positions: [
|
||||
'Quizmaster',
|
||||
'Wattergott Atheist',
|
||||
'Pessimist',
|
||||
'3x König',
|
||||
],
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<section
|
||||
id="team"
|
||||
class="container max-w-7xl mx-auto px-4 py-16 sm:py-24 lg:py-32"
|
||||
>
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-lg text-primary text-center mb-3 tracking-wider">
|
||||
Athleten
|
||||
</h2>
|
||||
|
||||
<h2 class="text-3xl md:text-4xl text-center font-bold">
|
||||
FC Dotterbühel Dream Team
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-6 md:gap-8 justify-center items-start"
|
||||
>
|
||||
{#each teamList as { imageUrl, firstName, lastName, positions }}
|
||||
<Card
|
||||
class="bg-muted/60 dark:bg-card flex flex-col h-full overflow-hidden group/hoverimg p-0 "
|
||||
>
|
||||
<CardHeader class="p-0 gap-0 ">
|
||||
<div class="h-full overflow-hidden">
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt={`${firstName} ${lastName}`}
|
||||
class="w-full bg-linear-to-bl from-lime-300 to-lime-950 aspect-square object-cover saturate-0 transition-all duration-300 ease-in-out group-hover/hoverimg:saturate-100 group-hover/hoverimg:scale-105"
|
||||
/>
|
||||
</div>
|
||||
<CardTitle class="p-4 sm:p-6">
|
||||
{firstName}
|
||||
<span class="text-primary">{lastName}</span>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
|
||||
<div class="px-4 sm:px-6 grow">
|
||||
{#each positions as position, index}
|
||||
<CardContent class="p-0 pb-2 text-muted-foreground">
|
||||
{position}{#if index < positions.length - 1},{/if}
|
||||
</CardContent>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<CardFooter class="space-x-4 px-4 sm:px-6 py-4"
|
||||
>Fc Dotterbühel</CardFooter
|
||||
>
|
||||
</Card>
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,27 @@
|
||||
<section class="mb-5">
|
||||
<a
|
||||
href="https://webwerkstatt.tirol"
|
||||
target="_blank"
|
||||
class="flex gap-2 w-72 mx-auto cursor-pointer text-xs bg-white dark:bg-black justify-center rounded-sm opacity-90 border border-gray-300 dark:border-gray-600"
|
||||
>
|
||||
<span>© 2026</span>
|
||||
<span class=" text-slate-500 dark:text-slate-400">made by</span>
|
||||
<span class=" tracking-tight text-xs font-bold">
|
||||
Web<span
|
||||
class="text-primary-800 font-black text-lime-600 dark:text-lime-500"
|
||||
>Werkstatt</span
|
||||
><span class="text-black dark:text-slate-400 font-light"
|
||||
>.tirol</span
|
||||
>
|
||||
</span>
|
||||
<div class="w-4 text-green-900 dark:text-lime-500">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M164 78a26 26 0 1 0-26-26a26 26 0 0 0 26 26m0-40a14 14 0 1 1-14 14a14 14 0 0 1 14-14m89.16 158.94l-54.56-92.08a13.9 13.9 0 0 0-12-6.86a13.88 13.88 0 0 0-12 6.86l-27.88 47.05l-46.56-79a14 14 0 0 0-24.13 0L2.83 197A6 6 0 0 0 8 206h240a6 6 0 0 0 5.16-9.06M86.27 79a2 2 0 0 1 3.46 0l25.34 43H60.93ZM18.5 194l35.36-60h68.29l19.3 32.77l16 27.2Zm152.93 0l-17.85-30.29L184.83 111a2 2 0 0 1 1.72-1a1.93 1.93 0 0 1 1.72 1l49.2 83Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<span>v 1.0</span>
|
||||
</a>
|
||||
</section>
|
||||
Reference in new issue
Block a user