Skip to content

Commit

Permalink
Redesign the website with proper theming, icons, typography, etc
Browse files Browse the repository at this point in the history
  • Loading branch information
sneakycrow committed Oct 31, 2024
1 parent 504bdef commit d16032b
Show file tree
Hide file tree
Showing 21 changed files with 471 additions and 223 deletions.
3 changes: 3 additions & 0 deletions packages/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,8 @@
"typescript": "^5.0.0",
"typescript-eslint": "^8.0.0",
"vite": "^5.0.3"
},
"dependencies": {
"@floating-ui/dom": "^1.6.12"
}
}
18 changes: 17 additions & 1 deletion packages/web/src/app.css

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions packages/web/src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap"
href="https://fonts.googleapis.com/css2?family=DM+Serif+Display&family=Outfit:wght@100;200;300;400;500;600;700;800;900&display=swap"
rel="stylesheet"
/>

%sveltekit.head%
</head>
<body
data-sveltekit-preload-data="hover"
class="min-w-screen dark:bg-primary-950 bg-primary-50 dark:text-primary-100 text-primary-950 min-h-screen text-base"
class="min-w-screen dark:grid-bg grid-light-bg min-h-screen bg-primary-50 text-base text-black dark:bg-primary-950 dark:text-white"
>
<div style="display: contents">%sveltekit.body%</div>
</body>
Expand Down
34 changes: 34 additions & 0 deletions packages/web/src/lib/components/Button.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<script lang="ts">
export let variant: 'primary' | 'secondary' = 'primary';
export let type: 'button' | 'submit' | 'reset' = 'button';
export let disabled = false;
export let href = '';
export let id = '';
</script>

{#if href}
<a
{id}
{href}
class="{$$restProps.class} inline-flex items-center justify-between rounded-sm border border-b-4 px-4 py-1 text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:pointer-events-none disabled:opacity-50 {variant ===
'primary'
? 'border-primary-900 bg-primary-700 text-white'
: 'border-secondary-600 bg-secondary-200 text-black'} "
on:click
>
<slot />
</a>
{:else}
<button
{id}
{type}
{disabled}
class="{$$restProps.class} inline-flex items-center justify-between rounded-sm border border-b-4 px-4 py-1 text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:pointer-events-none disabled:opacity-50 {variant ===
'primary'
? 'border-primary-900 bg-primary-700 text-white'
: 'border-secondary-600 bg-secondary-200 text-black'}"
on:click
>
<slot />
</button>
{/if}
16 changes: 16 additions & 0 deletions packages/web/src/lib/components/Footer.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<footer class="w-full py-8 text-black dark:text-white">
<div class="container mx-auto max-w-screen-lg px-4">
<div class="mt-8 pt-8 text-center text-sm">
<p>
Made with <span class="text-red-500">❤</span> by
<a
class="font-semibold underline hover:text-primary-800"
href="https://sneakycrow.dev"
target="_blank"
>
sneakycrow
</a>
</p>
</div>
</div>
</footer>
42 changes: 40 additions & 2 deletions packages/web/src/lib/components/Header.svelte
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
<header class="flex items-center justify-center p-4">
<h1 class="text-4xl">farmhand</h1>
<script lang="ts">
import Button from './Button.svelte';
import Logo from './Logo.svelte';
import MyAccount from './MyAccount.svelte';
import ThemeToggler from './ThemeToggler.svelte';
export let user: object | null = null;
</script>

<header class="flex w-full items-center justify-center text-black dark:text-white">
<nav class="flex w-full max-w-screen-lg items-center justify-between py-4 text-sm">
<ul class="flex items-center justify-start">
<li>
<a href="/" class="flex flex-nowrap items-center">
<Logo size={50} />
</a>
</li>
<li>
<a href="/about" class="mx-4">About</a>
</li>
<li>
<a href="/features" class="mx-4">Features</a>
</li>
<li>
<a href="/pricing" class="mx-4">Pricing</a>
</li>
<li>
<a href="/contact" class="mx-4">Contact</a>
</li>
</ul>
<aside class="flex items-center space-x-2">
{#if user}
<MyAccount />
{:else}
<Button href="/login">Log in</Button>
<Button href="/register">Register</Button>
{/if}
<ThemeToggler />
</aside>
</nav>
</header>
14 changes: 14 additions & 0 deletions packages/web/src/lib/components/Logo.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script lang="ts">
export let size = 100;
</script>

<svg width={size} height={size} viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<path
d="M50 10 L50 90 M30 20 L50 40 M70 20 L50 40 M40 10 L40 30 M60 10 L60 30"
stroke="currentColor"
stroke-width="4"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
134 changes: 134 additions & 0 deletions packages/web/src/lib/components/MyAccount.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<script lang="ts">
import { onMount } from 'svelte';
import { computePosition, flip, shift, offset } from '@floating-ui/dom';
import type { ComputePositionReturn } from '@floating-ui/dom';
import Button from './Button.svelte';
import SignOut from './icons/SignOut.svelte';
import Chevron from './icons/Chevron.svelte';
import MyAccount from './icons/MyAccount.svelte';
import { enhance } from '$app/forms';
let hideMenu: (ev?: Event) => void;
let account: HTMLElement | null;
let menu: HTMLElement | null;
onMount(() => {
account = document.getElementById('account');
menu = document.getElementById('menu');
console.log('With love, Sony AK <[email protected]>. GitHub: https://github.com/sonyarianto');
function update(el: HTMLElement) {
if (!menu) return;
computePosition(el, menu, {
placement: 'top',
middleware: [offset(6), flip(), shift({ padding: 5 })]
}).then(({ x, y }: ComputePositionReturn) => {
if (!menu) return;
Object.assign(menu.style, {
left: `${x}px`,
top: `${y}px`
});
});
}
function showMenu(ev: MouseEvent) {
if (!menu) return;
menu.style.display = 'block';
const targetElement = ev.currentTarget as HTMLElement;
const element = document.getElementById(targetElement.id);
if (element) {
update(element);
}
}
hideMenu = () => {
if (!menu) return;
menu.style.display = '';
};
if (account) {
account.addEventListener('click', showMenu);
}
});
function clickOutside(node: HTMLElement) {
const handleClick = (event: MouseEvent) => {
const target = event.target as Node;
if (node && !node.contains(target) && !event.defaultPrevented) {
node.dispatchEvent(new CustomEvent('clickoutside'));
}
};
document.addEventListener('click', handleClick, true);
return {
destroy() {
document.removeEventListener('click', handleClick, true);
}
};
}
export let user = {
name: 'sneakycrow',
email: '[email protected]'
};
</script>

<Button id="account">
<span>Account</span>
<Chevron
class="ml-2 transition-transform {menu?.style.display === 'block' ? 'rotate-180' : ''}"
/>
</Button>

<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
id="menu"
role="menu"
use:clickOutside
on:clickoutside={hideMenu}
on:click={hideMenu}
tabindex="0"
class="min-w-52 rounded border-2 border-primary-800 bg-primary-900"
>
<aside class="px-6 py-4 text-primary-50 dark:text-white">
<p class="text-xs font-medium">Signed in as</p>
<p class="text-lg font-semibold">{user.name}</p>
<p class="text-base text-primary-200 dark:text-primary-200">{user.email}</p>
</aside>
<hr class="border-primary-800" />
<ul class="p-2">
<li>
<a
href="/account"
class="flex w-full flex-nowrap items-center rounded px-4 py-2 font-semibold text-primary-50 hover:bg-primary-800 dark:text-white"
>
<MyAccount class="mr-2" />
<span>My Account</span>
</a>
</li>
<li>
<form action="?/logout" method="POST" use:enhance>
<button
class="flex w-full flex-nowrap items-center rounded px-4 py-2 font-semibold text-primary-50 hover:bg-primary-800 dark:text-white"
>
<SignOut class="mr-2" />
<span>Sign out</span>
</button>
</form>
</li>
</ul>
</div>

<style>
#menu {
display: none;
width: max-content;
position: absolute;
top: 0;
left: 0;
}
</style>
2 changes: 1 addition & 1 deletion packages/web/src/lib/components/ThemeToggler.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

<button
type="button"
class="text-primary-800 hover:bg-primary-100 focus:ring-primary-200 dark:text-primary-200 dark:hover:bg-primary-700 dark:focus:ring-primary-700 rounded-lg p-2.5 text-sm focus:outline-none focus:ring-4"
class="rounded-sm p-2 text-sm text-primary-800 hover:bg-primary-100 focus:outline-none focus:ring-4 focus:ring-primary-200 dark:text-primary-200 dark:hover:bg-primary-700 dark:focus:ring-primary-700"
on:click={toggleTheme}
>
{#if theme === 'dark'}
Expand Down
3 changes: 3 additions & 0 deletions packages/web/src/lib/components/icons/Chevron.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...$$props}>
<path fill="currentColor" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6l-6 6z" />
</svg>
6 changes: 6 additions & 0 deletions packages/web/src/lib/components/icons/MyAccount.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...$$props}>
<path
fill="currentColor"
d="M10 4a4 4 0 0 0-4 4a4 4 0 0 0 4 4a4 4 0 0 0 4-4a4 4 0 0 0-4-4m0 2a2 2 0 0 1 2 2a2 2 0 0 1-2 2a2 2 0 0 1-2-2a2 2 0 0 1 2-2m7 6q-.24 0-.24.24l-.26 1.26c-.22.18-.54.34-.78.5l-1.28-.5c-.08 0-.24 0-.32.1l-.96 1.76c-.08.08-.08.24.08.32l1.04.82v1l-1.04.82c-.08.08-.16.24-.08.32l.96 1.76c.08.1.24.1.32.1l1.28-.5c.24.16.56.32.78.5l.26 1.26q0 .24.24.24h2c.08 0 .24-.08.24-.24l.16-1.26c.32-.18.64-.34.88-.5l1.22.5c.14 0 .3 0 .3-.1l1.04-1.76c.08-.08 0-.24-.08-.32l-1.04-.82v-1l1.04-.82c.08-.08.16-.24.08-.32L21.8 13.6c0-.1-.16-.1-.3-.1l-1.22.5c-.24-.16-.56-.32-.88-.5l-.16-1.26c0-.16-.16-.24-.24-.24zm-7 1c-2.67 0-8 1.33-8 4v3h9.67c-.28-.59-.48-1.23-.58-1.9H3.9V17c0-.64 3.13-2.1 6.1-2.1c.43 0 .87.04 1.3.1c.2-.64.47-1.24.82-1.79c-.78-.13-1.52-.21-2.12-.21m8.04 2.5c.8 0 1.46.66 1.46 1.54c0 .8-.66 1.46-1.46 1.46c-.88 0-1.54-.66-1.54-1.46c0-.88.66-1.54 1.54-1.54"
/>
</svg>
6 changes: 6 additions & 0 deletions packages/web/src/lib/components/icons/SignOut.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...$$props}>
<path
fill="currentColor"
d="M4 12a1 1 0 0 0 1 1h7.59l-2.3 2.29a1 1 0 0 0 0 1.42a1 1 0 0 0 1.42 0l4-4a1 1 0 0 0 .21-.33a1 1 0 0 0 0-.76a1 1 0 0 0-.21-.33l-4-4a1 1 0 1 0-1.42 1.42l2.3 2.29H5a1 1 0 0 0-1 1M17 2H7a3 3 0 0 0-3 3v3a1 1 0 0 0 2 0V5a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1v-3a1 1 0 0 0-2 0v3a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V5a3 3 0 0 0-3-3"
/>
</svg>
16 changes: 16 additions & 0 deletions packages/web/src/routes/+error.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script>
import { page } from '$app/stores';
import Button from '$lib/components/Button.svelte';
</script>

<section class="flex min-h-[50vh] flex-col items-center justify-center space-y-4 text-center">
<h1 class="font-serif text-3xl text-primary-700 dark:text-primary-200">
{$page.status}: {$page.error?.message || 'Page not found'}
</h1>

<p class="text-gray-600 dark:text-gray-300">
Looks like you've wandered into uncharted territory!
</p>

<Button href="/">Back to Home</Button>
</section>
7 changes: 6 additions & 1 deletion packages/web/src/routes/+layout.server.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { LayoutServerLoad } from './$types';

export const load: LayoutServerLoad = async ({ locals }) => {
const tmpUser = {
name: 'sneakycrow'
};
const user: { name: string } | null = locals.authenticated ? tmpUser : null;
return {
authenticated: locals.authenticated
authenticated: locals.authenticated,
user
};
};
17 changes: 7 additions & 10 deletions packages/web/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@
import type { Snippet } from 'svelte';
let { data, children }: { data: LayoutData; children: Snippet } = $props();
import ThemeToggler from '$lib/components/ThemeToggler.svelte';
import Header from '$lib/components/Header.svelte';
import Footer from '$lib/components/Footer.svelte';
</script>

<Header />
<main>
{#if isAuthenticated}
<pre>{JSON.stringify(data, null, 2)}</pre>
{/if}
<div class="fixed right-4 top-4 z-50">
<ThemeToggler />
</div>
{@render children()}
<main class="flex min-h-screen flex-col">
<Header user={data.user} />
<section class="mx-auto min-h-full w-full max-w-screen-lg flex-grow p-4">
{@render children()}
</section>
<Footer />
</main>
12 changes: 12 additions & 0 deletions packages/web/src/routes/+page.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { redirect } from '@sveltejs/kit';
import type { Actions } from './$types';

export const actions = {
logout: async ({ cookies }) => {
// Remove the JWT cookie
cookies.delete('jwt', { path: '/' });

// Redirect to login page
throw redirect(303, '/login');
}
} satisfies Actions;
7 changes: 6 additions & 1 deletion packages/web/src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
index page
<section class="my-10 flex flex-col space-y-4 text-center">
<h1 class="font-serif text-3xl text-primary-700 dark:text-primary-200">
It's farming time, yeehaw
</h1>
<p>A fully featured clip and vod management software for creators and artists</p>
</section>
Loading

0 comments on commit d16032b

Please sign in to comment.