Skip to content

Commit 2b1b91e

Browse files
committed
✨ feat: update components, add new react components, add store script, redesign
1 parent d13258f commit 2b1b91e

File tree

12 files changed

+229
-103
lines changed

12 files changed

+229
-103
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { i18n, languages } from "../i18n/ui";
2+
3+
type Props = {
4+
visible?: boolean;
5+
defaultLanguage?: string;
6+
};
7+
8+
export default function(props: Props) {
9+
return <select name="Language" style={{
10+
display: props.visible ? "initial" : "none"
11+
}} value={props.defaultLanguage} onChange={(e) => {
12+
const htmlSelect = e.target as HTMLSelectElement;
13+
const splitPath: Array<string> = window.location.pathname.split('/');
14+
15+
window.location.pathname = `${htmlSelect.value}/${splitPath.splice(
16+
2, splitPath.length-1
17+
).join('/')}`;
18+
}}> {
19+
languages.map((lang, i) =>
20+
<option value={lang} key={i}>
21+
{ i18n[lang as keyof typeof i18n].language }
22+
</option>
23+
)
24+
} </select>
25+
}

src/components/ProjectCard.astro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ const { icon, developer, title, description, href } = Astro.props;
1616
<div class="developer">
1717
<Image class="icon" src={ icon ??
1818
`https://github.com/${developer}.png?size=72`
19-
} alt="dev profile picture" width={32} height={32} />
19+
} alt="dev profile picture" width={32} height={32} loading={"lazy"}
20+
/>
2021

2122
<span class="developer-name">{ developer }</span>
2223
</div>

src/components/ProjectsComponent.astro

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,11 @@
11
---
2-
import { useTranslations } from "../i18n/utils";
32
import ProjectCard, { type Project } from "./ProjectCard.astro";
43
5-
const tr = useTranslations(Astro.params.lang as never || "en");
6-
7-
const projects: Array<Project> = [
8-
{
9-
title: "colorshell",
10-
developer: "retrozinndev",
11-
description: "Super cool desktop shell for Hyprland!",
12-
href: "https://github.com/retrozinndev/colorshell"
13-
},
14-
{
15-
title: "retrozinndev.github.io",
16-
developer: "retrozinndev",
17-
description: "My personal website",
18-
href: "https://github.com/retrozinndev/retrozinndev.github.io"
19-
},
20-
{
21-
title: "parceirtoti.github.io",
22-
developer: "parceiroti",
23-
description: "ParceiroTI's website redesign",
24-
href: "https://github.com/parceiroti/parceiroti.github.io"
25-
},
26-
{
27-
title: "UpDateN'Time",
28-
developer: "retrozinndev",
29-
description: "A Tool that synchronizes your date and time with the internet",
30-
href: "https://github.com/retrozinndev/UpDateNTime"
31-
},
32-
{
33-
title: "The Traveler",
34-
developer: "notestudios",
35-
description: "A two-dimensional shooter game",
36-
href: "https://github.com/notestudios/TheTraveler"
37-
},
38-
{
39-
title: "Space Shooter",
40-
developer: "notestudios",
41-
description: "Shoot meteors in Space!",
42-
href: "https://github.com/notestudios/SpaceShooter"
43-
}
44-
];
4+
interface Props {
5+
projects: Array<Project>;
6+
}
457
8+
const { projects } = Astro.props;
469
---
4710

4811
<div class="projects"> {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useState, type ReactElement } from "react"
2+
import { getStoredTheme, getTheme, toggleTheme } from "../scripts/theme";
3+
import { RiMoonLine, RiSunLine } from "react-icons/ri";
4+
import { IconContext } from "react-icons";
5+
6+
export default function(props: { initialTheme?: "dark" | "light" }): ReactElement {
7+
const [stateTheme, setStateTheme] = useState(props.initialTheme ?? getStoredTheme()) as [
8+
("dark" | "light"), React.Dispatch<React.SetStateAction<"dark" | "light">>
9+
];
10+
11+
return (<div className="theme-toggle" onClick={() => {
12+
toggleTheme();
13+
setStateTheme(getTheme() as ("dark" | "light"));
14+
}} onLoad={() =>
15+
getStoredTheme() !== stateTheme &&
16+
setStateTheme(getStoredTheme() as ("dark" | "light"))
17+
} style={{
18+
cursor: "pointer"
19+
}}>
20+
<IconContext.Provider value={{
21+
className: "icon",
22+
size: "16",
23+
style: {
24+
marginTop: 2
25+
}
26+
}}> {
27+
stateTheme === "dark" ?
28+
<RiMoonLine />
29+
: <RiSunLine />
30+
} </IconContext.Provider>
31+
</div>);
32+
}

src/i18n/utils.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@
22
import type { i18nStruct } from "./struct.ts";
33
import { languages, i18n, defaultLang } from "./ui.ts";
44

5-
export function getLanguageFromURL(url: (URL|string)): (string) {
6-
const splittedURL: string[] = (typeof url === "string") ?
7-
url.split('/')
8-
: url.pathname.split("/");
9-
10-
return splittedURL[1].length !== 2 ?
11-
defaultLang
12-
: splittedURL[1];
5+
export function getLanguageFromURL(url: URL): (string|undefined) {
6+
const splitPath = url.pathname.split('/', 2);
7+
8+
return (splitPath[1] ?? false) && splitPath[1].length <= 5 ?
9+
splitPath[1]
10+
: undefined;
1311
}
1412

1513
export function useTranslations(lang: string): Function {

src/scripts/repositories.ts

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/scripts/stores.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { atom, type PreinitializedWritableAtom } from "nanostores";
2+
3+
export type AtomStoreType<AtomType> = PreinitializedWritableAtom<AtomType> & object & {
4+
key: string;
5+
};
6+
7+
const stores: Record<string, AtomStoreType<any>> = {} as const;
8+
export function addStore<StoreType = any>(key: string, initialValue: StoreType): AtomStoreType<StoreType> {
9+
if(Object.hasOwn(stores, key)) {
10+
console.warn(`Stores: there's already a key named \`${key}\``);
11+
return stores[key as keyof typeof stores];
12+
}
13+
14+
stores[key] = atom(initialValue);
15+
return stores[key];
16+
}
17+
18+
export function removeStore(key: string): boolean {
19+
if(Object.hasOwn(stores, key)) {
20+
stores[key as keyof typeof stores].off();
21+
delete stores[key as keyof typeof stores];
22+
return true;
23+
}
24+
25+
return false;
26+
}

src/scripts/theme.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ export function getThemes(): Array<string> {
1111
}
1212

1313
export function getStoredTheme(): (string|undefined) {
14-
return localStorage.getItem("theme")?.toString();
14+
if(typeof localStorage !== "undefined")
15+
return localStorage.getItem("theme")?.toString() ?? getThemes()[0];
16+
17+
return getThemes()[0];
1518
}
1619

1720
export function toggleTheme(): void {

src/styles/_colors.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ $link-color: #2f82c2;
1010
$emphasis-color: #2c73a5;
1111

1212
// General
13-
$accent-color: #e3cf62;
1413
$accent-color-dark: #a89b54;
14+
$accent-color: #e3cf62;
1515

src/styles/_fonts.scss

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1 @@
11
@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap");
2-
@import url("https://cdn.jsdelivr.net/gh/ryanoasis/nerd-fonts@latest/css/nerd-fonts-generated.min.css");
3-
4-
@font-face {
5-
font-family: "NerdFontsSymbols Nerd Font";
6-
src: url("https://cdn.jsdelivr.net/gh/ryanoasis/nerd-fonts@latest/patched-fonts/NerdFontsSymbolsOnly/SymbolsNerdFontMono-Regular.ttf");
7-
}

0 commit comments

Comments
 (0)