Layout Styles Update
This commit is contained in:
@@ -83,9 +83,3 @@ pub struct UpdateDocumentRequest {
|
||||
pub title: Option<String>,
|
||||
pub folder_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct UpdateFileRequest {
|
||||
pub name: Option<String>,
|
||||
pub folder_id: Option<String>,
|
||||
}
|
||||
|
||||
+5
-3
@@ -9,7 +9,9 @@
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
overflow: hidden;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
color-scheme: dark;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import Icon from '@iconify/svelte';
|
||||
</script>
|
||||
|
||||
<footer class="mt-auto py-6 text-center text-sm text-gray-500 dark:text-gray-400 border-t border-gray-200 dark:border-white/10 bg-[var(--theme-bg)] sticky bottom-0 w-full z-10 flex-shrink-0 transition-colors duration-200">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col justify-center items-center gap-4">
|
||||
<a
|
||||
href="https://github.com/SirBlobby/TypstDrive"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center gap-2 hover:text-gray-900 dark:hover:text-white transition-colors bg-gray-100 hover:bg-gray-200 dark:bg-white/5 dark:hover:bg-white/10 px-3 py-1.5 rounded-lg border border-transparent dark:border-white/10"
|
||||
>
|
||||
<Icon icon="mdi:github" class="text-xl" />
|
||||
<span class="font-semibold">GitHub Repository</span>
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -5,14 +5,22 @@
|
||||
file: any;
|
||||
deleteFile: (id: string, name: string) => void;
|
||||
}>();
|
||||
|
||||
let isFont = $derived(file.name.endsWith('.ttf') || file.name.endsWith('.otf'));
|
||||
|
||||
function handleOpen() {
|
||||
if (!isFont) {
|
||||
window.open(`/api/files/${file.id}/data`, '_blank');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="bg-white dark:bg-black/20 rounded-xl shadow-sm border border-gray-200 dark:border-white/10 p-6 flex flex-col hover:shadow-lg hover:border-green-400 dark:hover:border-green-500/50 transition-all duration-200 relative group transform hover:-translate-y-1 cursor-pointer"
|
||||
class="bg-white dark:bg-black/20 rounded-xl shadow-sm border border-gray-200 dark:border-white/10 p-6 flex flex-col transition-all duration-200 relative group transform hover:-translate-y-1 {isFont ? 'cursor-default' : 'hover:shadow-lg hover:border-green-400 dark:hover:border-green-500/50 cursor-pointer'}"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
onclick={() => window.open(`/api/files/${file.id}/data`, '_blank')}
|
||||
onkeydown={(e) => e.key === 'Enter' && window.open(`/api/files/${file.id}/data`, '_blank')}
|
||||
onclick={handleOpen}
|
||||
onkeydown={(e) => e.key === 'Enter' && handleOpen()}
|
||||
draggable="true"
|
||||
ondragstart={(e) => e.dataTransfer?.setData('text/plain', JSON.stringify({ type: 'file', id: file.id }))}
|
||||
>
|
||||
@@ -20,8 +28,10 @@
|
||||
<div class="p-3 bg-green-50 dark:bg-green-500/10 text-green-600 dark:text-green-400 rounded-lg overflow-hidden flex items-center justify-center w-12 h-12">
|
||||
{#if file.mime_type.startsWith('image/')}
|
||||
<img src={`/api/files/${file.id}/data`} alt={file.name} class="w-full h-full object-cover rounded" draggable="false" />
|
||||
{:else if isFont}
|
||||
<Icon icon="mdi:format-font" class="text-2xl" />
|
||||
{:else}
|
||||
<Icon icon="mdi:image-outline" class="text-2xl" />
|
||||
<Icon icon="mdi:file-outline" class="text-2xl" />
|
||||
{/if}
|
||||
</div>
|
||||
<button aria-label="Delete file" onclick={(e) => { e.stopPropagation(); deleteFile(file.id, file.name); }} class="pointer-events-auto text-gray-400 hover:text-red-500 dark:hover:text-red-400 opacity-0 group-hover:opacity-100 transition-opacity bg-gray-50 hover:bg-red-50 dark:bg-white/5 dark:hover:bg-red-900/20 rounded-full p-2 shadow-sm border border-gray-100 dark:border-white/10">
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<nav class="bg-white/80 dark:bg-black/20 backdrop-blur-md shadow-sm border-b border-gray-200 dark:border-white/10 px-6 py-4 flex justify-between items-center sticky top-0 z-10 transition-colors duration-200">
|
||||
<nav class="bg-[var(--theme-bg)] shadow-sm border-b border-gray-200 dark:border-white/10 px-6 py-4 flex justify-between items-center sticky top-0 z-10 transition-colors duration-200">
|
||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white flex items-center gap-3">
|
||||
<Icon icon="mdi:script-text" class="text-blue-600 dark:text-blue-400 text-3xl" />
|
||||
TypstDrive
|
||||
|
||||
@@ -28,13 +28,13 @@
|
||||
|
||||
{#if loaded}
|
||||
<div
|
||||
class="h-screen w-screen flex flex-col font-sans transition-colors duration-200"
|
||||
style="background-color: {currentColors.background}; color: {currentColors.text};"
|
||||
class="min-h-screen w-full flex flex-col font-sans transition-colors duration-200"
|
||||
style="background-color: {currentColors.background}; color: {currentColors.text}; --theme-bg: {currentColors.background};"
|
||||
>
|
||||
{@render children()}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="h-screen w-screen flex items-center justify-center bg-gray-50 dark:bg-zinc-950">
|
||||
<div class="min-h-screen w-full flex items-center justify-center bg-gray-50 dark:bg-zinc-950">
|
||||
<div class="text-gray-500 dark:text-gray-400 font-medium animate-pulse">Loading TypstDrive...</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import RenameModal from '$lib/components/dashboard/RenameModal.svelte';
|
||||
import CreateDocModal from '$lib/components/dashboard/CreateDocModal.svelte';
|
||||
import CreateFolderModal from '$lib/components/dashboard/CreateFolderModal.svelte';
|
||||
import Footer from '$lib/components/Footer.svelte';
|
||||
|
||||
let documents = $state<any[]>([]);
|
||||
let folders = $state<any[]>([]);
|
||||
@@ -321,12 +322,12 @@
|
||||
|
||||
<svelte:window onclick={handleWindowClick} />
|
||||
|
||||
<div class="min-h-screen bg-transparent flex flex-col">
|
||||
<div class="min-h-screen flex flex-col">
|
||||
|
||||
<Navbar />
|
||||
|
||||
|
||||
<main class="max-w-7xl w-full mx-auto py-10 px-4 sm:px-6 lg:px-8 flex-grow flex flex-col overflow-y-auto">
|
||||
<main class="max-w-7xl w-full mx-auto py-10 px-4 sm:px-6 lg:px-8 flex-grow block">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h2 class="text-3xl font-bold text-gray-900 dark:text-white tracking-tight">My Documents</h2>
|
||||
|
||||
@@ -379,14 +380,14 @@
|
||||
</div>
|
||||
|
||||
{#if loading}
|
||||
<div class="flex-grow flex items-center justify-center">
|
||||
<div class="min-h-[50vh] flex items-center justify-center">
|
||||
<div class="flex flex-col items-center gap-4 text-gray-500 dark:text-gray-400 animate-pulse">
|
||||
<Icon icon="mdi:loading" class="text-4xl animate-spin" />
|
||||
<p class="text-lg font-medium">Loading your workspace...</p>
|
||||
</div>
|
||||
</div>
|
||||
{:else if documents.length === 0 && folders.length === 0 && files.length === 0 && currentFolderId === null}
|
||||
<div class="flex-grow flex items-center justify-center">
|
||||
<div class="min-h-[50vh] flex items-center justify-center">
|
||||
<div class="text-center p-12 bg-white/50 dark:bg-black/20 backdrop-blur-sm rounded-2xl shadow-sm border border-gray-200 dark:border-white/10 max-w-md w-full">
|
||||
<div class="inline-flex items-center justify-center w-20 h-20 rounded-full bg-blue-100/50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 mb-6">
|
||||
<Icon icon="mdi:file-document-outline" class="text-4xl" />
|
||||
@@ -468,10 +469,12 @@
|
||||
{/if}
|
||||
|
||||
{#if documents.length === 0 && folders.length === 0 && files.length === 0}
|
||||
<div class="flex-grow flex items-center justify-center">
|
||||
<div class="min-h-[50vh] flex items-center justify-center">
|
||||
<p class="text-gray-500 dark:text-gray-400">This folder is empty.</p>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
<meta property="og:title" content={`${documentTitle} - TypstDrive`} />
|
||||
</svelte:head>
|
||||
|
||||
<div class="flex flex-col h-full relative">
|
||||
<div class="flex flex-col h-screen relative">
|
||||
<Toolbar title={documentTitle} docId={$page.params.id} />
|
||||
|
||||
<main class="flex-1 flex flex-col md:flex-row overflow-hidden relative">
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { userStore } from '$lib/ts/auth';
|
||||
import Icon from '@iconify/svelte';
|
||||
import Footer from '$lib/components/Footer.svelte';
|
||||
|
||||
let username = $state('');
|
||||
let password = $state('');
|
||||
@@ -42,65 +43,68 @@
|
||||
<meta name="description" content="Sign in to TypstDrive." />
|
||||
</svelte:head>
|
||||
|
||||
<div class="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 relative overflow-hidden bg-transparent">
|
||||
|
||||
<div class="absolute -top-40 -left-40 w-96 h-96 bg-blue-400/20 dark:bg-blue-600/10 rounded-full blur-3xl mix-blend-multiply"></div>
|
||||
<div class="absolute top-40 -right-40 w-96 h-96 bg-purple-400/20 dark:bg-purple-600/10 rounded-full blur-3xl mix-blend-multiply"></div>
|
||||
<div class="absolute -bottom-40 left-20 w-96 h-96 bg-indigo-400/20 dark:bg-indigo-600/10 rounded-full blur-3xl mix-blend-multiply"></div>
|
||||
<div class="min-h-screen flex flex-col relative overflow-hidden">
|
||||
<div class="flex-grow flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
|
||||
<div class="absolute -top-40 -left-40 w-96 h-96 bg-blue-400/20 dark:bg-blue-600/10 rounded-full blur-3xl mix-blend-multiply z-0"></div>
|
||||
<div class="absolute top-40 -right-40 w-96 h-96 bg-purple-400/20 dark:bg-purple-600/10 rounded-full blur-3xl mix-blend-multiply z-0"></div>
|
||||
<div class="absolute -bottom-40 left-20 w-96 h-96 bg-indigo-400/20 dark:bg-indigo-600/10 rounded-full blur-3xl mix-blend-multiply z-0"></div>
|
||||
|
||||
<div class="max-w-md w-full space-y-8 bg-white/80 dark:bg-black/40 backdrop-blur-xl p-10 rounded-2xl shadow-2xl border border-gray-200/50 dark:border-white/10 relative z-10">
|
||||
<div class="text-center">
|
||||
<div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-blue-100/50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-500 mb-6 mx-auto shadow-sm">
|
||||
<Icon icon="mdi:script-text" class="text-3xl" />
|
||||
<div class="max-w-md w-full space-y-8 bg-white/80 dark:bg-black/40 backdrop-blur-xl p-10 rounded-2xl shadow-2xl border border-gray-200/50 dark:border-white/10 relative z-10">
|
||||
<div class="text-center">
|
||||
<div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-blue-100/50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-500 mb-6 mx-auto shadow-sm">
|
||||
<Icon icon="mdi:script-text" class="text-3xl" />
|
||||
</div>
|
||||
<h2 class="text-3xl font-extrabold tracking-tight text-gray-900 dark:text-white">
|
||||
Welcome back
|
||||
</h2>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400 font-medium">
|
||||
Sign in to your TypstDrive workspace
|
||||
</p>
|
||||
</div>
|
||||
<h2 class="text-3xl font-extrabold tracking-tight text-gray-900 dark:text-white">
|
||||
Welcome back
|
||||
</h2>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400 font-medium">
|
||||
Sign in to your TypstDrive workspace
|
||||
</p>
|
||||
</div>
|
||||
<form class="mt-8 space-y-6" onsubmit={login}>
|
||||
<div class="space-y-5">
|
||||
<div>
|
||||
<label for="username" class="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-1.5">Username</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<Icon icon="mdi:account" class="text-gray-400 dark:text-gray-500" />
|
||||
<form class="mt-8 space-y-6" onsubmit={login}>
|
||||
<div class="space-y-5">
|
||||
<div>
|
||||
<label for="username" class="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-1.5">Username</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<Icon icon="mdi:account" class="text-gray-400 dark:text-gray-500" />
|
||||
</div>
|
||||
<input id="username" name="username" type="text" required bind:value={username} class="block w-full rounded-xl border border-gray-300 dark:border-white/20 pl-10 pr-3 py-2.5 bg-white/50 dark:bg-black/40 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 sm:text-sm transition-all duration-200" placeholder="Enter your username">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-1.5">Password</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<Icon icon="mdi:lock" class="text-gray-400 dark:text-gray-500" />
|
||||
</div>
|
||||
<input id="password" name="password" type="password" required bind:value={password} class="block w-full rounded-xl border border-gray-300 dark:border-white/20 pl-10 pr-3 py-2.5 bg-white/50 dark:bg-black/40 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 sm:text-sm transition-all duration-200" placeholder="••••••••">
|
||||
</div>
|
||||
<input id="username" name="username" type="text" required bind:value={username} class="block w-full rounded-xl border border-gray-300 dark:border-white/20 pl-10 pr-3 py-2.5 bg-white/50 dark:bg-black/40 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 sm:text-sm transition-all duration-200" placeholder="Enter your username">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-1.5">Password</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<Icon icon="mdi:lock" class="text-gray-400 dark:text-gray-500" />
|
||||
</div>
|
||||
<input id="password" name="password" type="password" required bind:value={password} class="block w-full rounded-xl border border-gray-300 dark:border-white/20 pl-10 pr-3 py-2.5 bg-white/50 dark:bg-black/40 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 sm:text-sm transition-all duration-200" placeholder="••••••••">
|
||||
|
||||
{#if errorMsg}
|
||||
<div class="flex items-center gap-2 text-red-600 bg-red-50 dark:bg-red-500/10 dark:text-red-400 p-3 rounded-lg text-sm border border-red-200 dark:border-red-500/20 shadow-sm animate-in slide-in-from-top-1 fade-in duration-200">
|
||||
<Icon icon="mdi:alert-circle" class="text-lg flex-shrink-0" />
|
||||
<span class="font-medium">{errorMsg}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if errorMsg}
|
||||
<div class="flex items-center gap-2 text-red-600 bg-red-50 dark:bg-red-500/10 dark:text-red-400 p-3 rounded-lg text-sm border border-red-200 dark:border-red-500/20 shadow-sm animate-in slide-in-from-top-1 fade-in duration-200">
|
||||
<Icon icon="mdi:alert-circle" class="text-lg flex-shrink-0" />
|
||||
<span class="font-medium">{errorMsg}</span>
|
||||
<div class="pt-2">
|
||||
<button type="submit" class="group w-full flex justify-center items-center gap-2 py-3 px-4 border border-transparent text-sm font-bold rounded-xl text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-zinc-900 focus:ring-blue-500 transition-all duration-200 shadow-md hover:shadow-lg transform hover:-translate-y-0.5">
|
||||
Sign In
|
||||
<Icon icon="mdi:arrow-right" class="text-lg group-hover:translate-x-1 transition-transform" />
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="pt-2">
|
||||
<button type="submit" class="group w-full flex justify-center items-center gap-2 py-3 px-4 border border-transparent text-sm font-bold rounded-xl text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-zinc-900 focus:ring-blue-500 transition-all duration-200 shadow-md hover:shadow-lg transform hover:-translate-y-0.5">
|
||||
Sign In
|
||||
<Icon icon="mdi:arrow-right" class="text-lg group-hover:translate-x-1 transition-transform" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="text-sm text-center pt-4 border-t border-gray-200 dark:border-white/10">
|
||||
</form>
|
||||
<div class="text-sm text-center mt-6 pt-4 border-t border-gray-200 dark:border-white/10">
|
||||
<span class="text-gray-500 dark:text-gray-400">New to TypstDrive? </span>
|
||||
<a href="/register" class="font-bold text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300 transition-colors hover:underline">
|
||||
Create an account
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { userStore } from '$lib/ts/auth';
|
||||
import Icon from '@iconify/svelte';
|
||||
import Footer from '$lib/components/Footer.svelte';
|
||||
|
||||
let username = $state('');
|
||||
let password = $state('');
|
||||
@@ -51,65 +52,68 @@
|
||||
<meta name="description" content="Create a new TypstDrive account." />
|
||||
</svelte:head>
|
||||
|
||||
<div class="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 relative overflow-hidden bg-transparent">
|
||||
|
||||
<div class="absolute -top-40 right-20 w-96 h-96 bg-emerald-400/20 dark:bg-emerald-600/10 rounded-full blur-3xl mix-blend-multiply"></div>
|
||||
<div class="absolute top-40 -left-20 w-96 h-96 bg-teal-400/20 dark:bg-teal-600/10 rounded-full blur-3xl mix-blend-multiply"></div>
|
||||
<div class="absolute -bottom-40 right-40 w-96 h-96 bg-blue-400/20 dark:bg-blue-600/10 rounded-full blur-3xl mix-blend-multiply"></div>
|
||||
<div class="min-h-screen flex flex-col relative overflow-hidden">
|
||||
<div class="flex-grow flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
|
||||
<div class="absolute -top-40 right-20 w-96 h-96 bg-emerald-400/20 dark:bg-emerald-600/10 rounded-full blur-3xl mix-blend-multiply z-0"></div>
|
||||
<div class="absolute top-40 -left-20 w-96 h-96 bg-teal-400/20 dark:bg-teal-600/10 rounded-full blur-3xl mix-blend-multiply z-0"></div>
|
||||
<div class="absolute -bottom-40 right-40 w-96 h-96 bg-blue-400/20 dark:bg-blue-600/10 rounded-full blur-3xl mix-blend-multiply z-0"></div>
|
||||
|
||||
<div class="max-w-md w-full space-y-8 bg-white/80 dark:bg-black/40 backdrop-blur-xl p-10 rounded-2xl shadow-2xl border border-gray-200/50 dark:border-white/10 relative z-10">
|
||||
<div class="text-center">
|
||||
<div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-blue-100/50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-500 mb-6 mx-auto shadow-sm">
|
||||
<Icon icon="mdi:account-plus" class="text-3xl" />
|
||||
<div class="max-w-md w-full space-y-8 bg-white/80 dark:bg-black/40 backdrop-blur-xl p-10 rounded-2xl shadow-2xl border border-gray-200/50 dark:border-white/10 relative z-10">
|
||||
<div class="text-center">
|
||||
<div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-blue-100/50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-500 mb-6 mx-auto shadow-sm">
|
||||
<Icon icon="mdi:account-plus" class="text-3xl" />
|
||||
</div>
|
||||
<h2 class="text-3xl font-extrabold tracking-tight text-gray-900 dark:text-white">
|
||||
Create an account
|
||||
</h2>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400 font-medium">
|
||||
Join TypstDrive to start collaborating
|
||||
</p>
|
||||
</div>
|
||||
<h2 class="text-3xl font-extrabold tracking-tight text-gray-900 dark:text-white">
|
||||
Create an account
|
||||
</h2>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400 font-medium">
|
||||
Join TypstDrive to start collaborating
|
||||
</p>
|
||||
</div>
|
||||
<form class="mt-8 space-y-6" onsubmit={register}>
|
||||
<div class="space-y-5">
|
||||
<div>
|
||||
<label for="username" class="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-1.5">Username</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<Icon icon="mdi:account" class="text-gray-400 dark:text-gray-500" />
|
||||
<form class="mt-8 space-y-6" onsubmit={register}>
|
||||
<div class="space-y-5">
|
||||
<div>
|
||||
<label for="username" class="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-1.5">Username</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<Icon icon="mdi:account" class="text-gray-400 dark:text-gray-500" />
|
||||
</div>
|
||||
<input id="username" name="username" type="text" required bind:value={username} class="block w-full rounded-xl border border-gray-300 dark:border-white/20 pl-10 pr-3 py-2.5 bg-white/50 dark:bg-black/40 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 sm:text-sm transition-all duration-200" placeholder="Choose a username">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-1.5">Password</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<Icon icon="mdi:lock" class="text-gray-400 dark:text-gray-500" />
|
||||
</div>
|
||||
<input id="password" name="password" type="password" required bind:value={password} class="block w-full rounded-xl border border-gray-300 dark:border-white/20 pl-10 pr-3 py-2.5 bg-white/50 dark:bg-black/40 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 sm:text-sm transition-all duration-200" placeholder="••••••••">
|
||||
</div>
|
||||
<input id="username" name="username" type="text" required bind:value={username} class="block w-full rounded-xl border border-gray-300 dark:border-white/20 pl-10 pr-3 py-2.5 bg-white/50 dark:bg-black/40 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 sm:text-sm transition-all duration-200" placeholder="Choose a username">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-1.5">Password</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<Icon icon="mdi:lock" class="text-gray-400 dark:text-gray-500" />
|
||||
</div>
|
||||
<input id="password" name="password" type="password" required bind:value={password} class="block w-full rounded-xl border border-gray-300 dark:border-white/20 pl-10 pr-3 py-2.5 bg-white/50 dark:bg-black/40 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 sm:text-sm transition-all duration-200" placeholder="••••••••">
|
||||
|
||||
{#if errorMsg}
|
||||
<div class="flex items-center gap-2 text-red-600 bg-red-50 dark:bg-red-500/10 dark:text-red-400 p-3 rounded-lg text-sm border border-red-200 dark:border-red-500/20 shadow-sm animate-in slide-in-from-top-1 fade-in duration-200">
|
||||
<Icon icon="mdi:alert-circle" class="text-lg flex-shrink-0" />
|
||||
<span class="font-medium">{errorMsg}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if errorMsg}
|
||||
<div class="flex items-center gap-2 text-red-600 bg-red-50 dark:bg-red-500/10 dark:text-red-400 p-3 rounded-lg text-sm border border-red-200 dark:border-red-500/20 shadow-sm animate-in slide-in-from-top-1 fade-in duration-200">
|
||||
<Icon icon="mdi:alert-circle" class="text-lg flex-shrink-0" />
|
||||
<span class="font-medium">{errorMsg}</span>
|
||||
<div class="pt-2">
|
||||
<button type="submit" class="group w-full flex justify-center items-center gap-2 py-3 px-4 border border-transparent text-sm font-bold rounded-xl text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-zinc-900 focus:ring-blue-500 transition-all duration-200 shadow-md hover:shadow-lg transform hover:-translate-y-0.5">
|
||||
Register
|
||||
<Icon icon="mdi:arrow-right" class="text-lg group-hover:translate-x-1 transition-transform" />
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="pt-2">
|
||||
<button type="submit" class="group w-full flex justify-center items-center gap-2 py-3 px-4 border border-transparent text-sm font-bold rounded-xl text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-zinc-900 focus:ring-blue-500 transition-all duration-200 shadow-md hover:shadow-lg transform hover:-translate-y-0.5">
|
||||
Register
|
||||
<Icon icon="mdi:arrow-right" class="text-lg group-hover:translate-x-1 transition-transform" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="text-sm text-center pt-4 border-t border-gray-200 dark:border-white/10">
|
||||
</form>
|
||||
<div class="text-sm text-center mt-6 pt-4 border-t border-gray-200 dark:border-white/10">
|
||||
<span class="text-gray-500 dark:text-gray-400">Already have an account? </span>
|
||||
<a href="/login" class="font-bold text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300 transition-colors hover:underline">
|
||||
Sign in
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { themes } from '$lib/ts/themes';
|
||||
import Icon from '@iconify/svelte';
|
||||
import ThemePicker from '$lib/components/ThemePicker.svelte';
|
||||
import Footer from '$lib/components/Footer.svelte';
|
||||
|
||||
let username = $state('');
|
||||
let isSaving = $state(false);
|
||||
@@ -106,8 +107,8 @@
|
||||
<meta name="description" content="Manage your TypstDrive settings." />
|
||||
</svelte:head>
|
||||
|
||||
<div class="h-screen overflow-y-auto bg-transparent flex flex-col">
|
||||
<nav class="bg-white/80 dark:bg-black/20 backdrop-blur-md shadow-sm border-b border-gray-200 dark:border-white/10 px-6 py-4 flex justify-between items-center sticky top-0 z-10 transition-colors duration-200 flex-shrink-0">
|
||||
<div class="min-h-screen flex flex-col">
|
||||
<nav class="bg-[var(--theme-bg)] shadow-sm border-b border-gray-200 dark:border-white/10 px-6 py-4 flex justify-between items-center sticky top-0 z-10 transition-colors duration-200 flex-shrink-0">
|
||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white flex items-center gap-3">
|
||||
<Icon icon="mdi:cog" class="text-blue-600 dark:text-blue-400 text-3xl" />
|
||||
Settings
|
||||
@@ -289,4 +290,5 @@
|
||||
</div>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
Reference in New Issue
Block a user