feat: refonte graphique complète du site.

This commit is contained in:
Nabil Ould Hamou 2024-01-07 04:14:21 +01:00
parent adc2b94513
commit b1a6f809ce
15 changed files with 621 additions and 194 deletions

417
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -32,6 +32,14 @@
},
"type": "module",
"dependencies": {
"svelte-icons": "^2.1.0"
"@radix-ui/react-slot": "^1.0.2",
"bits-ui": "^0.13.3",
"clsx": "^2.1.0",
"mode-watcher": "^0.1.2",
"radix-icons-svelte": "^1.2.1",
"svelte-icons": "^2.1.0",
"tailwind-merge": "^2.2.0",
"tailwind-variants": "^0.1.20",
"vaul-svelte": "^0.0.4"
}
}

View file

@ -1,8 +1,78 @@
@import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400;500;600;700&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
.content-container {
height: calc(100vh - theme('spacing.16'));
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 72.2% 50.6%;
--destructive-foreground: 0 0% 98%;
--ring: 240 10% 3.9%;
--radius: 0.5rem;
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--ring: 240 4.9% 83.9%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}

View file

@ -2,25 +2,39 @@ const projects = [
{
"name": "Portfolio",
"stack": ["SvelteKit", "TypeScript", "TailwindCSS"],
"description": "SvelteKit project to learn svelte and also update my personal website.",
"shortDesc": "Personal portfolio made using SvelteKit for learning purposes.",
"description": "This project is the website that you are actually using. This is my personal portfolio and used " +
"this project as an occasion to learn SvelteKit. In order to have an easier time with the design and make something " +
"good looking I also used TailwindCSS and Shadcn-svelte which is a binding for Shadcn/ui in Svelte. This project was " +
"the perfect occasion for me to learn and get more familiar with SvelteKit which is now my favorite framework for web developpment.",
"url": "https://github.com/nabilouldhamou/portfolio"
},
{
"name": "Green Plates",
"stack": ["GoLang", "GinGonic", "SvelteKit", "TypeScript"],
"description": "Recipe website with custom made backend using GoLang.",
"stack": ["Go", "GinGonic", "SvelteKit", "TypeScript"],
"shortDesc": "Recipe website with custom made backend using Go.",
"description": "Green Plates is a recipe sharing website made in collaboration with my friend @BenGregory23. " +
"This website is also made with SvelteKit for the frontend but also features a custom made high performance backend using Go and GinGonic. " +
"The website is still in a work in progress but the backend 99% done, only missing file fetching after the files are uploaded to the server.",
"url": "https://github.com/NabilOuldHamou?tab=repositories&q=green-plates&type=&language=&sort="
},
{
"name": "AnimeWorld",
"stack": ["Symfony 6", "PHP", "Nginx"],
"description": "University group project for the Web Server Programming class. I took the initiative to deploy the website on my VPS.",
"shortDesc": "University group project for my Web Server Programming class.",
"description": "For my Web Server Programming class, we were tasked with creating a website using Symfony 6 and other libraries, " +
"we decided to make an anime rating website, where users can create their own accounts are rate animes using a grade from 0 to 5 and also leave a comment. " +
"This project was the occasion for me to endorse a bit as a group leader by planning and taking care of the GitHub repository by giving some rules to follow to not compromise the repository. " +
"This was also the occasion for me to work once again on deploying a website on a Linux VPS by using Nginx and having to come up with the configuration needed for our website and also configure mailer, DNS and other domain related stuff.",
"url": "https://github.com/luxray555/projetsymfony"
},
{
"name": "EMG reader",
"stack": ["C", "Arduino"],
"description": "EMG reader for a friend in Biomedical Masters. The source code is private.",
"shortDesc": "EMG reader for a friend in Biomedical Masters.",
"description": "A friend in Biomedical Masters degree asked for my help to conceive a program, that would allow him to read the data from EMG using an Arduino board. " +
"I proceeded to write a program that can read the data from the EMG and send it to a computer where that data can be read and processed accordingly. " +
"My friend did not release the source code thus the project is considered proprietary.",
"url": ""
}
]

View file

@ -0,0 +1,29 @@
<script lang="ts">
import { Button } from "@/components/ui/button";
import * as Drawer from "@/components/ui/drawer";
import {HamburgerMenu} from "radix-icons-svelte";
import routes from "@/Routes";
export let path;
</script>
<Drawer.Root>
<Drawer.Trigger asChild let:builder>
<Button class="sm:hidden" variant="ghost" builders={[builder]}><HamburgerMenu class="w-6 h-6" /></Button>
</Drawer.Trigger>
<Drawer.Content>
<div class="mx-auto w-full max-w-sm mb-10">
<Drawer.Header>
<Drawer.Title>nbiloh.me</Drawer.Title>
</Drawer.Header>
<div class="p-4 pb-0">
<div class="flex flex-col gap-4 items-center justify-center space-x-2 text-muted-foreground">
{#each routes as route}
<Drawer.Close asChild let:builder>
<Button builders={[builder]} variant="ghost" class={`cursor-pointer ${path === route.href ? 'text-foreground font-bold' : 'hover:text-foreground'}`} href={route.href}>{route.name}</Button>
</Drawer.Close>
{/each}
</div>
</div>
</div>
</Drawer.Content>
</Drawer.Root>

View file

@ -0,0 +1,17 @@
<script lang="ts">
import { Button } from "@/components/ui/button";
import { Sun, Moon } from "radix-icons-svelte";
import {ModeWatcher, toggleMode} from "mode-watcher";
</script>
<ModeWatcher />
<Button on:click={toggleMode} variant="outline" size="icon">
<Sun
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"
/>
<Moon
class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"
/>
<span class="sr-only">Toggle theme</span>
</Button>

View file

@ -1,15 +1,19 @@
<script>
import routes from '$lib/Routes'
import LightSwitch from "@/components/LightSwitch.svelte";
import HamburgerMenu from "@/components/HamburgerMenu.svelte";
export let path;
</script>
<div class='h-14 w-full top-0 left-0 sticky flex justify-center items-center bg-dark-charcoal-gray'>
<div class='pt-4 w-4/5 flex justify-between'>
<img alt="Logo" src="/images/console.png" class='w-12 h-12' />
<div class='flex items-center justify-between sm:gap-x-8 gap-x-4 font-medium text-lg'>
<div class='h-14 w-full top-0 left-0 sticky flex justify-center items-center bg-background'>
<div class='pt-4 w-4/5 flex justify-between items-center'>
<span class="font-bold cursor-default">nbiloh.me</span>
<div class='hidden sm:visible sm:flex items-center justify-between sm:gap-x-8 gap-x-4 font-medium text-lg text-muted-foreground'>
{#each routes as route}
<a class={`cursor-pointer ${path === route.href ? 'text-accent' : 'hover:text-accent'}`} href={route.href}>{route.name}</a>
<a class={`cursor-pointer ${path === route.href ? 'text-foreground' : 'hover:text-foreground'}`} href={route.href}>{route.name}</a>
{/each}
</div>
<HamburgerMenu path={path} />
<LightSwitch />
</div>
</div>

View file

@ -1,14 +1,57 @@
<script lang="ts">
import * as Card from "@/components/ui/card";
import {Button, buttonVariants} from "@/components/ui/button";
import * as Dialog from "@/components/ui/dialog"
import {EyeNone, GithubLogo} from "radix-icons-svelte";
export let name: string;
export let stack: string;
export let shortDescription: string;
export let description: string;
export let url: string;
</script>
<a target='_blank' href='{url}'>
<div class='rounded-md border border-gray-200 max-w-xl text-center flex flex-col items-center justify-center flex-wrap hover:border-accent transition ease-in-out duration-500'>
<h1 class='text-blue-300 text-xl font-medium'>{name}</h1>
<h3 class='text-accent w-11/12 break-words'>{stack}</h3>
<p class='w-4/5'>{description}</p>
</div>
</a>
<Card.Root class="max-w-xs w-[320px]">
<Card.Header>
<Card.Title class="font-bold">{name}</Card.Title>
<Card.Description>{stack}</Card.Description>
</Card.Header>
<Card.Content>
<p>{shortDescription}</p>
</Card.Content>
<Card.Footer class="flex justify-between items-center">
{#if url === ""}
<Button disabled="true" variant="outline">
<EyeNone class="mr-2 h-4 w-4" />
Proprietary
</Button>
{:else }
<Button href={url} target="_blank" variant="outline">
<GithubLogo class="mr-2 h-4 w-4" />
View on GitHub
</Button>
{/if}
<Dialog.Root>
<Dialog.Trigger class={buttonVariants({ variant: "default" })}>View More</Dialog.Trigger>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>{name}</Dialog.Title>
<Dialog.Description>{stack}</Dialog.Description>
</Dialog.Header>
<p>{description}</p>
<Dialog.Footer>
{#if url === ""}
<Button disabled="true" variant="outline">
<EyeNone class="mr-2 h-4 w-4" />
Proprietary
</Button>
{:else }
<Button href={url} target="_blank" variant="outline">
<GithubLogo class="mr-2 h-4 w-4" />
View on GitHub
</Button>
{/if}
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>
</Card.Footer>
</Card.Root>

View file

@ -1,4 +1,4 @@
<div class='flex flex-col items-center justify-center w-full h-full'>
<h1 class='text-lg text-accent font-bold'>404</h1>
<h1 class='text-lg text-foreground font-bold'>404</h1>
<h3>This page does not exist.</h3>
</div>

View file

@ -9,12 +9,4 @@
<section class='content-container'>
<slot />
</section>
</main>
<style lang="postcss">
:global(html) {
font-family: theme(fontFamily.fira-code);
background-color: theme(colors.dark-charcoal-gray);
color: theme(colors.white-smoke);
}
</style>
</main>

View file

@ -1,18 +1,44 @@
<script lang="ts">
import FaGithub from 'svelte-icons/fa/FaGithub.svelte'
import FaTwitter from 'svelte-icons/fa/FaTwitter.svelte';
import FaRegFileAlt from 'svelte-icons/fa/FaRegFileAlt.svelte';
import {Button} from '@/components/ui/button'
import { GithubLogo } from "radix-icons-svelte";
import { TwitterLogo } from "radix-icons-svelte";
import { FileText } from "radix-icons-svelte";
import * as Card from "@/components/ui/card";
import * as Avatar from "@/components/ui/avatar"
</script>
<div class='flex flex-col justify-center items-center h-full font-bold text-center cursor-default'>
<div class='w-3/5'>
<h1 class='text-xl sm:text-4xl'>Hi I'm Nabil 👋</h1>
<p class='text-lg sm:text-2xl'>A <span class='text-accent'>Computer Science</span> student 🧑🏽‍💻 interested in <span class='text-accent'>embedded systems engineering</span> 🔋 Currently based in France 🇫🇷</p>
</div>
<div class='w-3/5 h-10 flex mt-8 justify-evenly'>
<a class='hover:text-accent cursor-pointer' href="https://github.com/nabilouldhamou" target="_blank"><FaGithub /></a>
<a class='hover:text-accent cursor-pointer' href="https://twitter.com/nbil_o" target="_blank"><FaTwitter /></a>
<a class='hover:text-accent cursor-pointer' href="/CV.pdf" target="_blank"><FaRegFileAlt /></a>
</div>
<div class='flex flex-col justify-center items-center h-full text-center cursor-default mt-20'>
<Card.Root class="max-w-xs sm:max-w-sm ease-in-out duration-500">
<Card.Header class="flex items-center">
<Card.Title>Nabil Ould Hamou</Card.Title>
<Card.Description>Computer Science Student</Card.Description>
<Avatar.Root class="h-32 w-32">
<Avatar.Image src="https://github.com/nabilouldhamou.png" alt="@nabilouldhamou" />
<Avatar.Fallback>NOH</Avatar.Fallback>
</Avatar.Root>
</Card.Header>
<Card.Content>
<p class="text-muted-foreground">Hi I am <span class="text-foreground font-bold">Nabil</span> 👋</p>
<p class="text-muted-foreground">I am a <span class="text-foreground">computer science student</span> 👨‍💻 interested in <span class="text-foreground">embedded systems engineering</span> 📟.</p>
</Card.Content>
<Card.Footer class="flex flex-col justify-center gap-2">
<div class="flex justify-center gap-1.5 sm:gap-3">
<Button href="https://github.com/nabilouldhamou" target='_blank' variant="outline">
<GithubLogo class="mr-2 h-4 w-4" />
Github
</Button>
<Button href="/CV.pdf" target='_blank' variant="outline">
<FileText class="mr-2 h-4 w-4" />
CV
</Button>
<Button href="https://x.com/nbil_o" target='_blank' variant="outline">
<TwitterLogo class="mr-2 h-4 w-4" />
Twitter
</Button>
</div>
<p class="font-bold">Contact: ouldhamounabil@gmail.com</p>
</Card.Footer>
</Card.Root>
</div>

View file

@ -1,7 +1,7 @@
<div class='flex flex-col justify-center items-center pt-6'>
<div class='text-justify w-4/5 lg:w-3/5'>
<h3 class='text-accent md:text-4xl text-3xl pb-5 font-bold'>About Me</h3>
<p class='sm:text-xl text-md'>Hello I am <span class='text-accent'>Nabil Ould Hamou</span>, a <span class='text-accent'>computer science student</span>.
<h1 class='md:text-4xl text-3xl pb-5 font-bold'>About Me</h1>
<p class='text-muted-foreground text-lg'>I am <span class='text-foreground font-bold'>Nabil Ould Hamou</span>, a <span class='text-foreground font-bold'>computer science student</span>.
I am currently studying computer science and making my way to become an embedded systems engineer. Since a very young age I always
loved tinkering, especially with electronics, anything from game consoles to computers. This curiosity led me into pursuing my dream
of become a computer scientist.</p>

View file

@ -3,13 +3,15 @@
import projects from '$lib/Projects'
</script>
<div class='flex flex-col items-center'>
<div class='flex flex-col justify-center items-center pt-6'>
<div class='w-4/5 lg:w-3/5'>
<h1 class='md:text-4xl text-3xl pb-5 font-bold'>Projects</h1>
</div>
<h1 class='text-accent text-4xl font-bold my-4'>Projects</h1>
<div class='flex flex-col gap-6 w-4/5 mb-6 items-center justify-center'>
<div class='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-6'>
{#each projects as project}
<Project name={project.name} stack={project.stack} description={project.description} url={project.url} />
<Project name={project.name} stack={project.stack} shortDescription={project.shortDesc} description={project.description} url={project.url} />
{/each}
</div>
</div>

View file

@ -11,7 +11,10 @@ const config = {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter()
adapter: adapter(),
alias: {
"@/*": "./src/lib",
},
}
};

View file

@ -1,20 +1,64 @@
import { fontFamily } from "tailwindcss/defaultTheme";
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{html,js,svelte,ts}'],
purge: ["./src/**/*.svelte"],
darkMode: true,
theme: {
extend: {
colors: {
'dark-charcoal-gray': '#111111',
'white-smoke': '#efefef',
'accent': '#f9f871',
'lighter-gray': '#333333',
},
fontFamily: {
'fira-code': ['Fira Code', 'monospace']
}
}
},
plugins: []
};
const config = {
darkMode: ["class"],
content: ["./src/**/*.{html,js,svelte,ts}"],
safelist: ["dark"],
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px"
}
},
extend: {
colors: {
border: "hsl(var(--border) / <alpha-value>)",
input: "hsl(var(--input) / <alpha-value>)",
ring: "hsl(var(--ring) / <alpha-value>)",
background: "hsl(var(--background) / <alpha-value>)",
foreground: "hsl(var(--foreground) / <alpha-value>)",
primary: {
DEFAULT: "hsl(var(--primary) / <alpha-value>)",
foreground: "hsl(var(--primary-foreground) / <alpha-value>)"
},
secondary: {
DEFAULT: "hsl(var(--secondary) / <alpha-value>)",
foreground: "hsl(var(--secondary-foreground) / <alpha-value>)"
},
destructive: {
DEFAULT: "hsl(var(--destructive) / <alpha-value>)",
foreground: "hsl(var(--destructive-foreground) / <alpha-value>)"
},
muted: {
DEFAULT: "hsl(var(--muted) / <alpha-value>)",
foreground: "hsl(var(--muted-foreground) / <alpha-value>)"
},
accent: {
DEFAULT: "hsl(var(--accent) / <alpha-value>)",
foreground: "hsl(var(--accent-foreground) / <alpha-value>)"
},
popover: {
DEFAULT: "hsl(var(--popover) / <alpha-value>)",
foreground: "hsl(var(--popover-foreground) / <alpha-value>)"
},
card: {
DEFAULT: "hsl(var(--card) / <alpha-value>)",
foreground: "hsl(var(--card-foreground) / <alpha-value>)"
}
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)"
},
fontFamily: {
sans: [...fontFamily.sans]
}
}
},
};
export default config;