still prototype ig, but improved hehe

This commit is contained in:
Mohamad 2025-01-29 18:15:27 +01:00
parent 38c19728e8
commit f903569a60
7 changed files with 492 additions and 19 deletions

View File

@ -11,6 +11,7 @@
"@capacitor/cli": "^7.0.1",
"@capacitor/core": "^7.0.1",
"@inlang/paraglide-sveltekit": "^0.15.5",
"lucide-svelte": "^0.474.0",
"motion": "^12.0.6"
},
"devDependencies": {
@ -4342,6 +4343,15 @@
"node": "18 >=18.20 || 20 || >=22"
}
},
"node_modules/lucide-svelte": {
"version": "0.474.0",
"resolved": "https://registry.npmjs.org/lucide-svelte/-/lucide-svelte-0.474.0.tgz",
"integrity": "sha512-yOSqjXPoEDOXCceBIfDaed6RinOvhp03ShiTXH6O+vlXE/NsyjQpktL8gm2vGDxi9d81HMuPFN1dwhVURh6mGg==",
"license": "ISC",
"peerDependencies": {
"svelte": "^3 || ^4 || ^5.0.0-next.42"
}
},
"node_modules/magic-string": {
"version": "0.30.17",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",

View File

@ -48,6 +48,7 @@
"@capacitor/cli": "^7.0.1",
"@capacitor/core": "^7.0.1",
"@inlang/paraglide-sveltekit": "^0.15.5",
"lucide-svelte": "^0.474.0",
"motion": "^12.0.6"
}
}

View File

@ -0,0 +1,95 @@
<script lang="ts">
import { Globe, Users, Plane, Instagram, Twitter, Youtube, MessageCircle, Heart } from "lucide-svelte";
const user = {
name: 'Adventure Alex',
bio: '🌍 Global Wanderer | Making friends one journey at a time',
location: 'Currently in Bali, Indonesia',
stats: [
{ label: 'Countries', value: 27, icon: Globe },
{ label: 'Friends', value: 143, icon: Users },
{ label: 'Trips', value: 89, icon: Plane }
],
upcomingTrips: [
{ id: 1, destination: 'Tokyo, Japan', date: 'March 15, 2024' },
{ id: 2, destination: 'Patagonia, Chile', date: 'April 20, 2024' }
],
socials: [
{ name: 'Instagram', handle: '@adventure_alex', url: '#', icon: Instagram },
{ name: 'Twitter', handle: '@wanderlust_alex', url: '#', icon: Twitter },
{ name: 'YouTube', handle: 'Adventure Alex', url: '#', icon: Youtube }
],
posts: [
{ id: 1, title: 'Sunset in Uluwatu 🌅', content: 'Chasing golden hours with amazing new friends! #BaliVibes', likes: 142, comments: 28, date: '2024-02-20' },
{ id: 2, title: 'Mountain Trekking 🏔️', content: 'Conquered Mount Batur at sunrise! Worth every step.', likes: 89, comments: 15, date: '2024-02-18' },
{ id: 3, title: 'Ocean Dive Adventure 🌊', content: 'Explored the coral reefs today. An unforgettable underwater experience!', likes: 134, comments: 24, date: '2024-02-25' },
{ id: 4, title: 'Cultural Exploration in Ubud 🏯', content: 'Spent the day visiting temples and enjoying the local culture. Bali, you are beautiful.', likes: 210, comments: 37, date: '2024-02-22' },
{ id: 5, title: 'Relaxing Beach Day 🏖️', content: 'Laid back by the waves with a coconut in hand. Pure bliss.', likes: 180, comments: 31, date: '2024-02-23' },
{ id: 6, title: 'Island Hopping 🌴', content: 'Visited Nusa Penida today. The cliffs and beaches are otherworldly!', likes: 250, comments: 48, date: '2024-02-24' },
{ id: 7, title: 'Bali Swing Adventure 🏞️', content: 'Took a swing over the jungle in Ubud. Pure adrenaline!', likes: 320, comments: 55, date: '2024-01-15' },
{ id: 8, title: 'Coffee Tasting in Ubud ☕', content: 'Explored the world of Bali coffee today! The Luwak coffee was a highlight!', likes: 145, comments: 22, date: '2024-01-17' },
{ id: 9, title: 'Sunrise at Tanah Lot ⛅', content: 'Witnessed one of the most breathtaking sunrises at Tanah Lot Temple. A must-see!', likes: 198, comments: 40, date: '2024-01-19' },
{ id: 10, title: 'Exploring Balis Waterfalls 🌿', content: 'Trekking through the jungle to reach these stunning waterfalls. A perfect adventure!', likes: 215, comments: 38, date: '2024-01-21' },
{ id: 11, title: 'Bali Beach Party 🎉', content: 'Danced the night away on the beach with new friends! Bali nights are unforgettable.', likes: 350, comments: 72, date: '2024-01-23' },
{ id: 12, title: 'Yoga Retreat in Ubud 🧘', content: 'Spent the weekend focusing on mindfulness and yoga. Feeling recharged!', likes: 215, comments: 50, date: '2024-01-25' }
]
};
const formatDate = (dateString: string) => {
const date = new Date(dateString);
return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
};
</script>
<section class="p-6">
<h2 class="mb-6 text-2xl font-bold text-gray-900">Recent Posts</h2>
<div class="space-y-4">
{#each user.posts as post}
<div class="post-card border border-gray-200 rounded-xl bg-white p-4 hover:bg-gray-50 transition-colors">
<div class="flex gap-3">
<!-- User Avatar -->
<div class="flex-shrink-0">
<img
src="https://w7.pngwing.com/pngs/48/259/png-transparent-profile-man-male-photo-face-portrait-illustration-vector-people-blue.png"
alt="Adventure Alex"
class="h-12 w-12 rounded-full border-2 border-blue-200"
/>
</div>
<!-- Tweet Content -->
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 text-sm">
<span class="font-bold text-gray-900">{user.name}</span>
<span class="text-gray-500">
{user.socials.find(s => s.name === 'Twitter')?.handle}
</span>
<span class="text-gray-400">·</span>
<time class="text-gray-500" datetime={post.date}>
{formatDate(post.date)}
</time>
</div>
<!-- Tweet Body -->
<p class="mt-2 text-gray-900 leading-relaxed">
{post.content}
</p>
<!-- Tweet Actions -->
<div class="mt-3 flex gap-6 text-gray-500">
<button class="flex items-center gap-2 hover:text-blue-500 transition-colors">
<MessageCircle size={18} />
<span class="text-sm">{post.comments}</span>
</button>
<button class="flex items-center gap-2 hover:text-red-500 transition-colors">
<Heart size={18} />
<span class="text-sm">{post.likes}</span>
</button>
</div>
</div>
</div>
</div>
{/each}
</div>
</section>

View File

@ -0,0 +1,263 @@
<script lang="ts">
import { onMount } from 'svelte';
import { animate } from 'motion';
import {
Globe,
Users,
Plane,
Calendar,
Heart,
MessageCircle,
Instagram,
Twitter,
Youtube
} from 'lucide-svelte';
import { fade } from 'svelte/transition';
let floating = false;
let isFollowing = false;
const user = {
name: 'Adventure Alex',
bio: '🌍 Global Wanderer | Making friends one journey at a time',
location: 'Currently in Bali, Indonesia',
stats: [
{ label: 'Countries', value: 27, icon: Globe },
{ label: 'Friends', value: 143, icon: Users },
{ label: 'Trips', value: 89, icon: Plane }
],
upcomingTrips: [
{ id: 1, destination: 'Tokyo, Japan', date: 'March 15, 2024' },
{ id: 2, destination: 'Patagonia, Chile', date: 'April 20, 2024' }
],
socials: [
{ name: 'Instagram', handle: '@adventure_alex', url: '#', icon: Instagram },
{ name: 'Twitter', handle: '@wanderlust_alex', url: '#', icon: Twitter },
{ name: 'YouTube', handle: 'Adventure Alex', url: '#', icon: Youtube }
],
posts: [
{
id: 1,
title: 'Sunset in Uluwatu 🌅',
content: 'Chasing golden hours with amazing new friends! #BaliVibes',
likes: 142,
comments: 28,
date: '2024-02-20'
},
{
id: 2,
title: 'Mountain Trekking 🏔️',
content: 'Conquered Mount Batur at sunrise! Worth every step.',
likes: 89,
comments: 15,
date: '2024-02-18'
}
]
};
const toggleFollow = () => {
isFollowing = !isFollowing;
};
onMount(() => {
const header = document.querySelector('.profile-header') as any;
const stats = document.querySelectorAll('.stat-card') as any;
const posts = document.querySelectorAll('.post-card') as any;
const trips = document.querySelectorAll('.trip-card') as any;
const plane = document.querySelector('.floating-plane') as any;
if (header) {
animate(header, { opacity: [0, 1], y: [-20, 0] }, {
duration: 0.8,
easing: 'easeOut'
} as any);
}
stats.forEach((stat: any, index: any) => {
animate(stat, { opacity: [0, 1], scale: [0.8, 1] }, {
delay: index * 0.1,
duration: 0.5,
easing: 'easeOut'
} as any);
});
posts.forEach((post: any, index: any) => {
animate(post, { opacity: [0, 1], y: [20, 0] }, {
delay: 0.3 + index * 0.1,
duration: 0.6,
easing: 'easeOut'
} as any);
});
trips.forEach((trip: any, index: any) => {
animate(trip, { opacity: [0, 1], x: [-20, 0] }, {
delay: 0.4 + index * 0.1,
duration: 0.7,
easing: 'easeOut'
} as any);
});
if (plane) {
setInterval(() => {
animate(plane, { y: floating ? -10 : 0 }, { duration: 1.5, easing: 'easeInOut' } as any);
floating = !floating;
}, 3000);
}
});
const formatDate = (dateString: string) => {
const date = new Date(dateString);
return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
};
</script>
<div class="h-full overflow-scroll bg-gray-100 py-8">
<!-- Floating Airplane -->
<div class="floating-plane absolute right-10 top-20 text-blue-500">
<Plane size={48} class="-rotate-45 transform" />
</div>
<main class="mx-auto max-w-4xl overflow-hidden rounded-xl bg-white shadow-xl">
<!-- Profile Header -->
<section
class="profile-header relative bg-gradient-to-b from-blue-100 to-white p-8 text-center"
>
<div class="mx-auto h-32 w-32 overflow-hidden rounded-full border-4 border-blue-500">
<img
src="https://w7.pngwing.com/pngs/48/259/png-transparent-profile-man-male-photo-face-portrait-illustration-vector-people-blue.png"
alt="Adventure Alex"
class="h-full w-full object-cover"
/>
</div>
<h1 class="mt-4 text-2xl font-bold text-gray-900">{user.name}</h1>
<p class="max-h-fit text-sm text-gray-500">{user.socials[0].handle}</p>
<p class="text-sm text-gray-500">{user.location}</p>
<p class="text-gray-600">{user.bio}</p>
<!-- Follow Button -->
<button
on:click={toggleFollow}
class="btn btn-primary mt-4 transform rounded-full px-6 py-2 text-sm font-medium transition-all hover:scale-105 focus:outline-none
{isFollowing ? 'btn-secondary' : ''}"
>
{isFollowing ? 'Following' : 'Follow'}
</button>
</section>
<!-- Social Media Links -->
<div in:fade={{ duration: 400 }} class="flex justify-center gap-6 bg-blue-50 py-4">
{#each user.socials as social}
<a
href={social.url}
target="_blank"
rel="noopener noreferrer"
class="flex items-center gap-2 text-gray-600 transition-colors hover:text-blue-500"
aria-label={`Visit ${social.name} profile`}
>
<svelte:component this={social.icon} size={20} />
<span class="text-sm font-medium">{social.handle}</span>
</a>
{/each}
</div>
<!-- Stats -->
<section class="grid grid-cols-3 gap-4 p-8">
{#each user.stats as stat}
<div class="stat-card rounded-lg bg-white p-6 text-center shadow-md">
<svelte:component this={stat.icon} class="mb-2 text-blue-500" size={24} />
<h3 class="text-3xl font-bold text-gray-900">{stat.value}</h3>
<p class="text-sm text-gray-600">{stat.label}</p>
</div>
{/each}
</section>
<!-- Recent Posts -->
<section class="p-6">
<h2 class="mb-6 text-2xl font-bold text-gray-900">Recent Adventures</h2>
<div class="space-y-4">
{#each user.posts as post}
<div
class="post-card rounded-xl border border-gray-200 bg-white p-4 transition-colors hover:bg-gray-50"
>
<div class="flex gap-3">
<!-- User Avatar -->
<div class="flex-shrink-0">
<img
src="https://w7.pngwing.com/pngs/48/259/png-transparent-profile-man-male-photo-face-portrait-illustration-vector-people-blue.png"
alt="Adventure Alex"
class="h-12 w-12 rounded-full border-2 border-blue-200"
/>
</div>
<!-- Tweet Content -->
<div class="min-w-0 flex-1">
<div class="flex items-center gap-2 text-sm">
<span class="font-bold text-gray-900">{user.name}</span>
<span class="text-gray-500">
{user.socials.find((s) => s.name === 'Twitter')?.handle}
</span>
<span class="text-gray-400">·</span>
<time class="text-gray-500" datetime={post.date}>
{formatDate(post.date)}
</time>
</div>
<!-- Tweet Body -->
<p class="mt-2 leading-relaxed text-gray-900">
{post.content}
</p>
<!-- Tweet Actions -->
<div class="mt-3 flex gap-6 text-gray-500">
<button class="flex items-center gap-2 transition-colors hover:text-blue-500">
<MessageCircle size={18} />
<span class="text-sm">{post.comments}</span>
</button>
<button class="flex items-center gap-2 transition-colors hover:text-red-500">
<Heart size={18} />
<span class="text-sm">{post.likes}</span>
</button>
</div>
</div>
</div>
</div>
{/each}
</div>
</section>
<!-- Upcoming Trips -->
<section class="p-8">
<h2 class="mb-6 text-2xl font-bold text-gray-900">Upcoming Trips</h2>
<div class="space-y-6">
{#each user.upcomingTrips as trip}
<div
class="trip-card flex items-center justify-between rounded-lg bg-white p-6 shadow-lg"
>
<div>
<h3 class="text-xl font-bold text-gray-900">{trip.destination}</h3>
<div class="flex items-center gap-2 text-gray-600">
<Calendar size={16} /> <time datetime={trip.date}>{trip.date}</time>
-
<Calendar size={16} /> <time datetime={trip.date}>{trip.date}</time>
</div>
</div>
<button class="btn btn-primary rounded-full px-6 py-2 text-sm font-medium">
Join Trip
</button>
</div>
{/each}
</div>
</section>
</main>
</div>
<style>
/* Custom hover effect */
.hover-scale {
transition: transform 150ms ease-out;
}
.hover-scale:hover {
transform: translateY(-2px);
}
</style>

View File

@ -1 +0,0 @@
<a href="/demo/paraglide">paraglide</a>

View File

@ -1,18 +0,0 @@
<script lang="ts">
import type { AvailableLanguageTag } from '$lib/paraglide/runtime';
import { i18n } from '$lib/i18n';
import { page } from '$app/state';
import { goto } from '$app/navigation';
import * as m from '$lib/paraglide/messages.js';
function switchToLanguage(newLanguage: AvailableLanguageTag) {
const canonicalPath = i18n.route(page.url.pathname);
const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage);
goto(localisedPath);
}
</script>
<h1>{m.hello_world({ name: 'SvelteKit User' })}</h1>
<div>
<button onclick={() => switchToLanguage('en')}>en</button>
</div>

View File

@ -0,0 +1,123 @@
<script>
import { animate, inView } from 'motion';
import { onMount } from 'svelte';
const planePath = "M13 11.5V7.5L16 8.5L19 4.5L22 8.5L25 7.5V11.5L22 12.5L25 16.5L22 20.5L19 16.5L16 20.5L13 16.5V11.5Z";
let email = '';
let password = '';
function handleSubmit() {
// Add your signin logic
}
function floatPlane() {
animate("#paper-plane",
// @ts-ignore
{ y: [-10, 10] },
{ duration: 2, repeat: Infinity, direction: "alternate" }
);
}
onMount(() => {
// Page load animations
animate("#form-container",
{ y: [50, 0], opacity: [0, 1] },
{ duration: 0.8 }
);
animate("#paper-plane",
{ x: [-100, 0], rotate: [-45, 0] },
{ duration: 1 }
);
floatPlane();
animate(".route-line",
{ strokeDashoffset: [100, 0] },
{ duration: 2, delay: 0.5 }
);
});
</script>
<div class="min-h-screen bg-base-200 relative overflow-hidden">
<!-- Background Elements -->
<div class="absolute inset-0 opacity-10">
<!-- Add your map/route background SVG here -->
<svg class="w-full h-full">
<path
d="M100,200 Q250,150 400,200"
class="route-line fill-none stroke-primary stroke-2"
style="stroke-dasharray: 100px;"
/>
</svg>
</div>
<!-- Main Content -->
<div class="flex items-center justify-center min-h-screen">
<!-- Paper Plane Decor -->
<div id="paper-plane" class="absolute left-1/4 top-1/3 opacity-50">
<svg class="w-32 h-32 text-primary" viewBox="0 0 32 32">
<path fill="currentColor" d="{planePath}" />
</svg>
</div>
<!-- Form Container -->
<div id="form-container" class="card bg-base-100 shadow-xl w-96 relative z-10">
<div class="card-body">
<h2 class="card-title text-3xl mb-6">Welcome Back, Explorer! ✈️</h2>
<form on:submit|preventDefault={handleSubmit}>
<div class="form-control">
<label class="label">
<span class="label-text">Email</span>
</label>
<input
type="email"
bind:value={email}
placeholder="your.email@adventure.com"
class="input input-bordered"
/>
</div>
<div class="form-control mt-4">
<label class="label">
<span class="label-text">Password</span>
</label>
<input
type="password"
bind:value={password}
placeholder="••••••••"
class="input input-bordered"
/>
</div>
<button
class="btn btn-primary mt-6 w-full"
>
Let's Travel Together! 🌍
</button>
</form>
<div class="divider my-6">New Adventurer?</div>
<a
href="/signup"
class="btn btn-outline btn-secondary w-full"
>
Create Travel Profile 🧳
</a>
</div>
</div>
</div>
</div>
<style>
/* Add custom paper texture if needed */
.paper-texture {
background-image: url('paper-texture.png');
mix-blend-mode: multiply;
}
</style>