Revamped landing page and mobile nav #7
14
src/app.html
14
src/app.html
@ -3,13 +3,19 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<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=Josefin+Sans:ital,wght@0,100..700;1,100..700&display=swap" rel="stylesheet">
|
||||
<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=Josefin+Sans:ital,wght@0,100..700;1,100..700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover" class="bg-stone-200 dark:bg-primary-900 text-primary-900 dark:text-stone-200 font-jose font-light">
|
||||
<body
|
||||
data-sveltekit-preload-data="hover"
|
||||
class="bg-stone-200 dark:bg-primary-900 text-primary-900 dark:text-stone-200 font-jose font-light"
|
||||
>
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
|
51
src/lib/BottomNavigation.svelte
Normal file
51
src/lib/BottomNavigation.svelte
Normal file
@ -0,0 +1,51 @@
|
||||
<script>
|
||||
import { BottomNav, BottomNavItem, Button, ButtonGroup } from 'flowbite-svelte';
|
||||
import {
|
||||
HomeSolid,
|
||||
ProfileCardOutline,
|
||||
ImageOutline,
|
||||
MobilePhoneOutline
|
||||
} from 'flowbite-svelte-icons';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
let activeBtn = writable('');
|
||||
|
||||
function handleNavItemClick(btnName) {
|
||||
activeBtn.set(btnName);
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if $activeBtn === 'projects'}
|
||||
<ButtonGroup class="fixed md:hidden bottom-20 flex justify-center w-full">
|
||||
<Button href="/projects/svelte" outline class="flex-col backdrop-blur ">Svelte</Button>
|
||||
<Button href="/projects/nextjs" outline class="flex-col backdrop-blur">Next.js</Button>
|
||||
<Button href="/projects/homelab" outline class="flex-col backdrop-blur">Homelab</Button>
|
||||
</ButtonGroup>
|
||||
{/if}
|
||||
|
||||
<BottomNav
|
||||
position="fixed"
|
||||
classInner="grid-cols-4"
|
||||
outerClass="md:hidden w-full z-50 border-gray-200 dark:bg-slate-900 dark:border-gray-600"
|
||||
>
|
||||
<BottomNavItem btnName="home" href="/" on:click={() => handleNavItemClick('home')}>
|
||||
<HomeSolid
|
||||
class="w-6 h-6 mb-1 text-gray-500 dark:text-gray-400 group-hover:text-primary-600 dark:group-hover:text-primary-500"
|
||||
/>
|
||||
</BottomNavItem>
|
||||
<BottomNavItem btnName="whoami" href="/about" on:click={() => handleNavItemClick('whoami')}>
|
||||
<ProfileCardOutline
|
||||
class="w-6 h-6 mb-1 text-gray-500 dark:text-gray-400 group-hover:text-primary-600 dark:group-hover:text-primary-500"
|
||||
/>
|
||||
</BottomNavItem>
|
||||
<BottomNavItem btnName="projects" on:click={() => handleNavItemClick('projects')}>
|
||||
<ImageOutline
|
||||
class="w-6 h-6 mb-1 text-gray-500 dark:text-gray-400 group-hover:text-primary-600 dark:group-hover:text-primary-500"
|
||||
/>
|
||||
</BottomNavItem>
|
||||
<BottomNavItem btnName="contact" href="/contact" on:click={() => handleNavItemClick('contact')}>
|
||||
<MobilePhoneOutline
|
||||
class="w-6 h-6 mb-1 text-gray-500 dark:text-gray-400 group-hover:text-primary-600 dark:group-hover:text-primary-500"
|
||||
/>
|
||||
</BottomNavItem>
|
||||
</BottomNav>
|
17
src/lib/Landing/VendorCarousel.svelte
Normal file
17
src/lib/Landing/VendorCarousel.svelte
Normal file
@ -0,0 +1,17 @@
|
||||
<script>
|
||||
import { Marquee } from 'flowbite-svelte';
|
||||
import { projects } from '$lib/projects.js';
|
||||
import VendorIcon from '../ProjectCard/VendorIcon.svelte';
|
||||
|
||||
const allVendors = Array.from(
|
||||
new Map(
|
||||
projects.flatMap((project) => project.vendors).map((vendor) => [vendor.name, vendor])
|
||||
).values()
|
||||
);
|
||||
</script>
|
||||
|
||||
<div class="p-4 bg-stone-200 dark:bg-slate-800 rounded-xl flex items-center overflow-scroll gap-4">
|
||||
{#each allVendors as vendor}
|
||||
<VendorIcon {...vendor} />
|
||||
{/each}
|
||||
</div>
|
21
src/lib/Landing/VendorMarquee.svelte
Normal file
21
src/lib/Landing/VendorMarquee.svelte
Normal file
@ -0,0 +1,21 @@
|
||||
<script>
|
||||
import { Marquee } from 'flowbite-svelte';
|
||||
import { projects } from '$lib/projects.js';
|
||||
import VendorIcon from '../ProjectCard/VendorIcon.svelte';
|
||||
|
||||
const allVendors = Array.from(
|
||||
new Map(
|
||||
projects.flatMap((project) => project.vendors).map((vendor) => [vendor.name, vendor])
|
||||
).values()
|
||||
);
|
||||
</script>
|
||||
|
||||
<Marquee
|
||||
speed={0.5}
|
||||
hoverSpeed={0.25}
|
||||
class="py-4 bg-stone-200 dark:bg-slate-800 rounded-xl flex items-center"
|
||||
>
|
||||
{#each allVendors as vendor}
|
||||
<VendorIcon {...vendor} />
|
||||
{/each}
|
||||
</Marquee>
|
@ -7,6 +7,6 @@
|
||||
<a href={url}>
|
||||
<div class="flex flex-col justify-center h-16 hover:scale-110">
|
||||
<img src={img} alt={name} class="min-h-12 max-w-12 self-center" />
|
||||
<p>{name}</p>
|
||||
<p class="text-slate-900 dark:text-stone-200 font-normal">{name}</p>
|
||||
</div>
|
||||
</a>
|
||||
|
48
src/lib/TopNav.svelte
Normal file
48
src/lib/TopNav.svelte
Normal file
@ -0,0 +1,48 @@
|
||||
<script>
|
||||
import {
|
||||
Navbar,
|
||||
NavBrand,
|
||||
NavLi,
|
||||
NavUl,
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
DarkMode
|
||||
} from 'flowbite-svelte';
|
||||
import { ChevronDownOutline } from 'flowbite-svelte-icons';
|
||||
import logo from '$lib/logo.png';
|
||||
import { page } from '$app/stores';
|
||||
|
||||
$: activeUrl = $page.url.pathname;
|
||||
</script>
|
||||
|
||||
<Navbar class="bg-transparent">
|
||||
<NavBrand href="/">
|
||||
<img src={logo} class="me-3 h-6 sm:h-9" alt="Flowbite Logo" />
|
||||
<span class="self-center whitespace-nowrap text-xl font-semibold dark:text-stone-200"
|
||||
>rannes.dev</span
|
||||
>
|
||||
</NavBrand>
|
||||
<div class="flex">
|
||||
<DarkMode btnClass="block sm:hidden" />
|
||||
</div>
|
||||
<NavUl class="md:flex-row" {activeUrl}>
|
||||
<NavLi href="/">home</NavLi>
|
||||
<NavLi href="/about">whoami</NavLi>
|
||||
<NavLi class="cursor-pointer">
|
||||
projects<ChevronDownOutline class="w-6 h-6 text-primary-800 dark:text-stone-200 inline" />
|
||||
</NavLi>
|
||||
<Dropdown
|
||||
{activeUrl}
|
||||
activeClass="font-bold text-primary-800 dark:text-stone-200"
|
||||
class="w-44 z-20"
|
||||
>
|
||||
<DropdownItem href="/projects/svelte">svelte</DropdownItem>
|
||||
<DropdownItem href="/projects/nextjs">nextjs</DropdownItem>
|
||||
<DropdownItem href="/projects/homelab">homelab</DropdownItem>
|
||||
</Dropdown>
|
||||
<NavLi href="/contact">contact</NavLi>
|
||||
<NavLi class="hidden sm:block">
|
||||
<DarkMode btnClass="p-0" />
|
||||
</NavLi>
|
||||
</NavUl>
|
||||
</Navbar>
|
BIN
src/lib/images/hero.webp
Normal file
BIN
src/lib/images/hero.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 MiB |
BIN
src/lib/images/localWeather.png
Normal file
BIN
src/lib/images/localWeather.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
BIN
src/lib/images/portfolio.png
Normal file
BIN
src/lib/images/portfolio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 89 KiB |
@ -1,55 +1,24 @@
|
||||
<script>
|
||||
import {
|
||||
Navbar,
|
||||
NavBrand,
|
||||
NavLi,
|
||||
NavUl,
|
||||
NavHamburger,
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
DarkMode
|
||||
} from 'flowbite-svelte';
|
||||
import { ChevronDownOutline, HomeOutline } from 'flowbite-svelte-icons';
|
||||
import '../app.css';
|
||||
import CloudflareAnalytics from '$lib/CloudflareAnalytics.svelte';
|
||||
import logo from '$lib/logo.png';
|
||||
import { page } from '$app/stores';
|
||||
import BottomNavigation from '../lib/BottomNavigation.svelte';
|
||||
import TopNav from '../lib/TopNav.svelte';
|
||||
|
||||
$: activeUrl = $page.url.pathname;
|
||||
let activeBtn = 'home';
|
||||
function handleNavItemClick(btnName) {
|
||||
activeBtn = btnName;
|
||||
}
|
||||
$: activeBtn = activeBtn === 'projects';
|
||||
</script>
|
||||
|
||||
<CloudflareAnalytics />
|
||||
<Navbar class="bg-transparent">
|
||||
<NavBrand href="/">
|
||||
<img src={logo} class="me-3 h-6 sm:h-9" alt="Flowbite Logo" />
|
||||
<span class="self-center whitespace-nowrap text-xl font-semibold dark:text-stone-200"
|
||||
>rannes.dev</span
|
||||
>
|
||||
</NavBrand>
|
||||
<div class="flex">
|
||||
<DarkMode btnClass="block sm:hidden" />
|
||||
<NavHamburger />
|
||||
</div>
|
||||
<NavUl {activeUrl}>
|
||||
<NavLi href="/">home</NavLi>
|
||||
<NavLi href="/about">whoami</NavLi>
|
||||
<NavLi class="cursor-pointer">
|
||||
projects<ChevronDownOutline class="w-6 h-6 text-primary-800 dark:text-stone-200 inline" />
|
||||
</NavLi>
|
||||
<Dropdown class="w-44 z-20">
|
||||
<DropdownItem href="/projects/svelte">svelte</DropdownItem>
|
||||
<DropdownItem href="/projects/nextjs">nextjs</DropdownItem>
|
||||
<DropdownItem href="/projects/homelab">homelab</DropdownItem>
|
||||
</Dropdown>
|
||||
<NavLi href="/contact">contact</NavLi>
|
||||
<NavLi class="hidden sm:block">
|
||||
<DarkMode btnClass="p-0" />
|
||||
</NavLi>
|
||||
</NavUl>
|
||||
</Navbar>
|
||||
<div class="px-2 sm:px-0 mx-auto max-w-xs sm:max-w-md md:max-w-3xl text-center">
|
||||
<TopNav />
|
||||
<div class="px-2 sm:px-0 mx-auto max-w-xs sm:max-w-md md:max-w-3xl text-center mb-20 md:mb-0">
|
||||
<slot />
|
||||
</div>
|
||||
<footer class="mt-12 text-center">
|
||||
<p class="text-sm text-stone-400">built by christian rannes 2024</p>
|
||||
<BottomNavigation />
|
||||
<footer class="">
|
||||
<div class="hidden md:block text-sm text-stone-400 mt-12 text-center">
|
||||
<p>built by christian rannes 2024</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -1,11 +1,43 @@
|
||||
<div class="main-container text-center">
|
||||
<h1 class="text-xl mb-2">Welcome to my corner of the internet</h1>
|
||||
<p>
|
||||
You most likely ended up here after listening to me rambling about the wonders of self hosted
|
||||
services, and how life would be much easier if we could just containerize everything.
|
||||
</p>
|
||||
<p class="italic text-sm mt-8">
|
||||
This page is my initial svelte project to try out the framework, and at the time of writing
|
||||
(24th April 2024) many pages are still lacking content.
|
||||
</p>
|
||||
<script>
|
||||
import VendorMarquee from '$lib/Landing/VendorMarquee.svelte';
|
||||
import VendorCarousel from '../lib/Landing/VendorCarousel.svelte';
|
||||
import { Heading, Mark } from 'flowbite-svelte';
|
||||
import portfolio from '$lib/images/portfolio.png';
|
||||
import hero from '$lib/images/hero.webp';
|
||||
|
||||
const images = [
|
||||
{
|
||||
title: '/projects/nextjs',
|
||||
image: portfolio
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<div class="text-center text-xl">
|
||||
<div class="flex my-4 gap-4">
|
||||
<Heading tag="h1" class="md:text-right">father by day <Mark>developer</Mark> by night</Heading>
|
||||
<img
|
||||
src={hero}
|
||||
alt=""
|
||||
class="hidden md:block rounded-xl max-h-36 w-auto shadow-inner border border-slate-700"
|
||||
/>
|
||||
</div>
|
||||
<h2 class="py-2">
|
||||
welcome to my space. For now it is used to document my learnings and share my projects. It might
|
||||
expand over time.
|
||||
</h2>
|
||||
<p class="py-2">
|
||||
I like to explore many different technologies and frameworks mostly surrounding web development
|
||||
and infrastructure.
|
||||
</p>
|
||||
<div class="hidden md:block py-2">
|
||||
<VendorMarquee />
|
||||
</div>
|
||||
<div class="md:hidden py-2">
|
||||
<VendorCarousel />
|
||||
</div>
|
||||
<h2 class="py-2">
|
||||
You can see some of my web dev projects and a small write-up on my homelab in the projects
|
||||
section.
|
||||
</h2>
|
||||
</div>
|
||||
|
@ -1,17 +1,36 @@
|
||||
<script>
|
||||
import migImg from "$lib/images/mig.jpg"
|
||||
import osImg from "$lib/images/os.webp"
|
||||
import { fade } from "svelte/transition";
|
||||
import migImg from '$lib/images/mig.jpg';
|
||||
import osImg from '$lib/images/os.webp';
|
||||
import { fade } from 'svelte/transition';
|
||||
import PageHeader from '$lib/PageHeader.svelte';
|
||||
const title = 'Life is good in Copenhagen';
|
||||
</script>
|
||||
|
||||
<div class="page-container" in:fade>
|
||||
<h1 class="text-xl mb-4">Life is good in Copenhagen</h1>
|
||||
<PageHeader {title} />
|
||||
<div class="article-container md:flex mb-4 items-center text-left">
|
||||
<p class="">I live in Copenhagen with my partner and children near the water. We love going on expeditions around the city in our cargo bike, or on my electrical skateboard.
|
||||
When we're not outside I spend a lot of time fiddling around with my homelab, and development projects. You can read more about my projects and homelab under the homelab and portfolio nav.
|
||||
<p class="">
|
||||
I live in Copenhagen with my partner and children near the water. We love going on expeditions
|
||||
around the city in our cargo bike, or on my electrical skateboard. When we're not outside I
|
||||
spend a lot of time fiddling around with my homelab, and development projects. You can read
|
||||
more about my projects and homelab under the homelab and portfolio nav.
|
||||
</p>
|
||||
<img class="rounded-2xl xl:ml-4 md:w-auto md:h-52 md:ml-0 md:mt-4 sm:ml-0 sm:mt-4 sm:w-full" src={migImg} alt="crazy man"/>
|
||||
<img
|
||||
class="rounded-2xl xl:ml-4 md:w-auto md:h-52 md:ml-0 md:mt-4 sm:ml-0 sm:mt-4 sm:w-full"
|
||||
src={migImg}
|
||||
alt="crazy man"
|
||||
/>
|
||||
</div>
|
||||
<p class="mb-4 ">I work in recruitment, and I specialise in building product teams for start ups and scale ups for a small recruitment agency called <a class="underline font-semibold" href="https://www.adveniopeople.com">Advenio People</a></p>
|
||||
<img src={osImg} alt="A happy man and a beautiful woman both wearing facemasks." class="rounded-full w-1/2 h-auto m-auto">
|
||||
<p class="mb-4">
|
||||
I work in recruitment, and I specialise in building product teams for start ups and scale ups
|
||||
for a small recruitment agency called <a
|
||||
class="underline font-semibold"
|
||||
href="https://www.adveniopeople.com">Advenio People</a
|
||||
>
|
||||
</p>
|
||||
<img
|
||||
src={osImg}
|
||||
alt="A happy man and a beautiful woman both wearing facemasks."
|
||||
class="rounded-full w-1/2 h-auto m-auto"
|
||||
/>
|
||||
</div>
|
@ -1 +1,13 @@
|
||||
<h1>Under development</h1>
|
||||
<script>
|
||||
import PageHeader from '$lib/PageHeader.svelte';
|
||||
const title = 'Coming soon!';
|
||||
</script>
|
||||
|
||||
<PageHeader {title} />
|
||||
<p class="py-6">
|
||||
For now you can hit me up on <a
|
||||
class="font-normal underline"
|
||||
href="https://www.linkedin.com/in/christian-rannes/"
|
||||
target="_blank">linkedin</a
|
||||
>
|
||||
</p>
|
||||
|
@ -3,10 +3,12 @@
|
||||
import asrockImg from '$lib/images/asrock.webp';
|
||||
import rackImg from '$lib/images/rack.webp';
|
||||
import { fade } from 'svelte/transition';
|
||||
import PageHeader from '$lib/PageHeader.svelte';
|
||||
const title = 'Homelab';
|
||||
</script>
|
||||
|
||||
<div in:fade>
|
||||
<h1 class="text-2xl mb-4">Homelab</h1>
|
||||
<PageHeader {title} />
|
||||
|
||||
<div class="content text-left">
|
||||
<article>
|
||||
@ -24,9 +26,9 @@
|
||||
maker-culture.
|
||||
</p>
|
||||
<p>
|
||||
My lab started in 2020, when I wanted to set up my own DNS server at home, to add
|
||||
network wide ad-block (Pihole). As I learned more about Linux and containerization I quickly
|
||||
got drawn into the hobby of self-hosting web-services.
|
||||
My lab started in 2020, when I wanted to set up my own DNS server at home, to add network
|
||||
wide ad-block (Pihole). As I learned more about Linux and containerization I quickly got
|
||||
drawn into the hobby of self-hosting web-services.
|
||||
</p>
|
||||
<p>
|
||||
Raspberry Pi's are great, but but the computing resources are limited compared to a x86, so
|
||||
@ -80,9 +82,11 @@
|
||||
<p>
|
||||
The homelab is also connected to two 3D printers, that are running open source custom
|
||||
firmware (klipper) and controlled through a web interface (Mainsail) from any device in the
|
||||
local network. I started with a Ender3, and during my parental leave last year I built <a class="underline" href="https://vorondesign.com/voron0.2">Voron 0.2</a>. The parts are all sourced, and the
|
||||
rest of the parts are 3D printed in ABS+. It took me roughly 40 hours to build it and
|
||||
calibrate it.
|
||||
local network. I started with a Ender3, and during my parental leave last year I built <a
|
||||
class="underline"
|
||||
href="https://vorondesign.com/voron0.2">Voron 0.2</a
|
||||
>. The parts are all sourced, and the rest of the parts are 3D printed in ABS+. It took me
|
||||
roughly 40 hours to build it and calibrate it.
|
||||
</p>
|
||||
<h2 class="text-xl text-center mt-4">OS</h2>
|
||||
<p>
|
||||
@ -116,8 +120,7 @@
|
||||
<li>Portfolio web page</li>
|
||||
<p class="italic pl-4">
|
||||
This is my portfolio page, which will soon be available at rannes.dev. I'm using
|
||||
svelte/sveltekit. It is
|
||||
currently not exposed to the internet as I am still building it.
|
||||
svelte/sveltekit. It is currently not exposed to the internet as I am still building it.
|
||||
</p>
|
||||
<li>Crowdsec Security Engine</li>
|
||||
<li>Prometheus</li>
|
||||
@ -152,9 +155,16 @@
|
||||
</p>
|
||||
<p>This VM has the SATA controller passed through, for full control of the HDD's.</p>
|
||||
<h3 class="text-lg text-center mt-4">Development server</h3>
|
||||
<p>This vm is my development server. It's running a act_runner paired up with Gitea to build my portfolio project, dockerize it and push it to my container registry. The application then deployed in the staging environment for a last check.</p>
|
||||
<p>
|
||||
This vm is my development server. It's running a act_runner paired up with Gitea to build my
|
||||
portfolio project, dockerize it and push it to my container registry. The application then
|
||||
deployed in the staging environment for a last check.
|
||||
</p>
|
||||
<h2 class="text-xl text-center mt-4">CI/CD</h2>
|
||||
<p>I use Gitea Actions which is similar to Github Actions. I will post a guide soon how to set up CI for your svelte-docker project with Gitea Actions.</p>
|
||||
<p>
|
||||
I use Gitea Actions which is similar to Github Actions. I will post a guide soon how to set
|
||||
up CI for your svelte-docker project with Gitea Actions.
|
||||
</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user