improved website
This commit is contained in:
Generated
+8
-47
@@ -10,8 +10,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"grommet-icons": "^4.12.1",
|
"grommet-icons": "^4.12.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0"
|
||||||
"react-router-dom": "^6.23.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.2.66",
|
"@types/react": "^18.2.66",
|
||||||
@@ -1074,14 +1073,6 @@
|
|||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@remix-run/router": {
|
|
||||||
"version": "1.16.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz",
|
|
||||||
"integrity": "sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.17.2",
|
"version": "4.17.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz",
|
||||||
@@ -1741,12 +1732,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/braces": {
|
"node_modules/braces": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fill-range": "^7.0.1"
|
"fill-range": "^7.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@@ -2451,9 +2442,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"to-regex-range": "^5.0.1"
|
"to-regex-range": "^5.0.1"
|
||||||
@@ -3492,36 +3483,6 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-router": {
|
|
||||||
"version": "6.23.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz",
|
|
||||||
"integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@remix-run/router": "1.16.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": ">=16.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-router-dom": {
|
|
||||||
"version": "6.23.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz",
|
|
||||||
"integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@remix-run/router": "1.16.1",
|
|
||||||
"react-router": "6.23.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": ">=16.8",
|
|
||||||
"react-dom": ">=16.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/read-cache": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
|
|||||||
+1
-2
@@ -12,8 +12,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"grommet-icons": "^4.12.1",
|
"grommet-icons": "^4.12.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0"
|
||||||
"react-router-dom": "^6.23.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.2.66",
|
"@types/react": "^18.2.66",
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import InputBox from './InputBox';
|
||||||
|
|
||||||
|
export default function ContactForm() {
|
||||||
|
const [ error, setError ] = useState<string>("");
|
||||||
|
const [ success, setSuccess ] = useState<boolean>(false);
|
||||||
|
const [ inputState, setInputState ] = useState<{name: string, email: string, subject: string, message: string}>({
|
||||||
|
name: "",
|
||||||
|
email: "",
|
||||||
|
subject: "",
|
||||||
|
message: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = () => {
|
||||||
|
if (
|
||||||
|
inputState.name === ""
|
||||||
|
|| inputState.email === ""
|
||||||
|
|| inputState.subject === ""
|
||||||
|
|| inputState.message === ""
|
||||||
|
) {
|
||||||
|
setError("A required field was missing")
|
||||||
|
} else {
|
||||||
|
console.log("Form submitted")
|
||||||
|
|
||||||
|
fetch("https://api.alexav.gg/v4/contact", {
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(inputState)
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.ok) {
|
||||||
|
setSuccess(true)
|
||||||
|
} else {
|
||||||
|
setError("An error occurred while submitting your info.")
|
||||||
|
}
|
||||||
|
}).catch((e) => {
|
||||||
|
console.error(e)
|
||||||
|
setError("An error occurred while submitting your info.")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setError("")
|
||||||
|
}, 6000)
|
||||||
|
}, [error]);
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setSuccess(false)
|
||||||
|
}, 6000)
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-white rounded-lg text-black p-2">
|
||||||
|
<h1 className="text-2xl font-bold">Contact Me</h1>
|
||||||
|
<hr className="my-2 border-black" />
|
||||||
|
|
||||||
|
<div className="space-y-2">
|
||||||
|
<InputBox
|
||||||
|
isText={true}
|
||||||
|
name="name"
|
||||||
|
placeholder="Name.."
|
||||||
|
onChange={(value: string) => {
|
||||||
|
setInputState((prevState) => {
|
||||||
|
return {
|
||||||
|
...prevState,
|
||||||
|
name: value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<InputBox
|
||||||
|
name="email"
|
||||||
|
isText={true}
|
||||||
|
placeholder="Email.."
|
||||||
|
onChange={(value: string) => {
|
||||||
|
setInputState((prevState) => {
|
||||||
|
return {
|
||||||
|
...prevState,
|
||||||
|
email: value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<InputBox
|
||||||
|
isText={true}
|
||||||
|
name="subject"
|
||||||
|
placeholder="Subject.."
|
||||||
|
onChange={(value: string) => {
|
||||||
|
setInputState((prevState) => {
|
||||||
|
return {
|
||||||
|
...prevState,
|
||||||
|
subject: value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<InputBox
|
||||||
|
isText={false}
|
||||||
|
name="message"
|
||||||
|
placeholder="Message.."
|
||||||
|
onChange={(value: string) => {
|
||||||
|
setInputState((prevState) => {
|
||||||
|
return {
|
||||||
|
...prevState,
|
||||||
|
message: value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="block">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="bg-black w-full text-white font-bold rounded-lg p-2"
|
||||||
|
onClick={onSubmit}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
<p className="text-red-400 font-bold text-center">{error}</p>
|
||||||
|
<p className="font-bold text-center">{ success && "Success! Your message has been received"}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -15,8 +15,9 @@ export default function Footer() {
|
|||||||
}, [mailState])
|
}, [mailState])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-zinc-600 text-center text-white absolute bottom-0 left-0 right-0 p-4 select-none">
|
<div className="bg-zinc-600 text-center text-white bottom-0 left-0 right-0 p-4 select-none">
|
||||||
<h1 className="font-bold">© {new Date().getFullYear()}, Alex Frantz. All Rights Reserved</h1>
|
<h1 className="font-bold">© {new Date().getFullYear()}, Alex Frantz. All Rights Reserved</h1>
|
||||||
|
<p>All logos & images on this page belong to their respective owners.</p>
|
||||||
|
|
||||||
{
|
{
|
||||||
mailState ? (
|
mailState ? (
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
export default function Header() {
|
export default function Header() {
|
||||||
return (
|
return (
|
||||||
<div className="text-white pt-4">
|
<div className="text-white pt-4 mx-auto lg:w-1/2 sm:w-full">
|
||||||
<h1 className="font-bold text-2xl">Alex Frantz</h1>
|
<h1 className="font-bold text-2xl">Alex Frantz</h1>
|
||||||
<p>Professional button clicker & word typer</p>
|
<p>Professional button clicker & word typer</p>
|
||||||
<div className="inline-block space-x-2">
|
|
||||||
<a className="font-bold hover:underline" href="/">Home</a>
|
|
||||||
<a className="font-bold hover:underline" href="experience">Experience</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr className="my-4" />
|
<hr className="my-4" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
export default function InputBox({
|
||||||
|
name,
|
||||||
|
placeholder,
|
||||||
|
isText = true,
|
||||||
|
onChange
|
||||||
|
}: {
|
||||||
|
name: string,
|
||||||
|
isText?: boolean,
|
||||||
|
placeholder: string,
|
||||||
|
onChange: (value: string) => void
|
||||||
|
}) {
|
||||||
|
if (isText) {
|
||||||
|
return (
|
||||||
|
<div className="block">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name={name}
|
||||||
|
placeholder={placeholder}
|
||||||
|
className="bg-black rounded-lg p-2 text-white w-full"
|
||||||
|
onChange={({target}) => onChange(target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<div className="block">
|
||||||
|
<textarea
|
||||||
|
name={name}
|
||||||
|
placeholder={placeholder}
|
||||||
|
onChange={({ target }) => onChange(target.value)}
|
||||||
|
className="bg-black rounded-lg p-2 text-white w-full h-32"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
export default function ListBox({
|
||||||
|
title,
|
||||||
|
points
|
||||||
|
}: {
|
||||||
|
title: string,
|
||||||
|
points: string[]
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="bg-slate-100 text-black rounded-lg p-4">
|
||||||
|
<h3 className="text-lg font-bold">{title}</h3>
|
||||||
|
<ul className="mt-2 space-y-2 text-muted-foreground">
|
||||||
|
{
|
||||||
|
points.map((v,k) => {
|
||||||
|
return <li key={k}>{v}</li>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
+18
-37
@@ -1,51 +1,32 @@
|
|||||||
export default function Project({
|
export default function Project({
|
||||||
name,
|
name,
|
||||||
|
image,
|
||||||
description,
|
description,
|
||||||
urlTo,
|
urlTo
|
||||||
subtitle,
|
|
||||||
bullets
|
|
||||||
}: {
|
}: {
|
||||||
name: string,
|
name: string,
|
||||||
|
image: string,
|
||||||
description: string,
|
description: string,
|
||||||
urlTo?: string,
|
urlTo?: string,
|
||||||
subtitle?: string,
|
|
||||||
bullets?: string[]
|
|
||||||
}) {
|
}) {
|
||||||
const mapBullets = () => {
|
|
||||||
return bullets?.map((v,k) => {
|
|
||||||
return <li className="list-inside list-disc" key={k}>{v}</li>
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white text-black p-2">
|
<a href={urlTo} target="_blank">
|
||||||
<div className="float-left">
|
<div className="bg-white text-black max-w-fit mx-auto rounded-lg overflow-hidden">
|
||||||
<p className="pl-2 text-2xl font-bold">{name}
|
<img
|
||||||
{
|
src={image}
|
||||||
urlTo ? (
|
width="400"
|
||||||
<a className="text-sm hover:underline pl-2" target="_blank" href={urlTo}>
|
height="300"
|
||||||
Project Website
|
alt={name}
|
||||||
</a>
|
className="w-full h-48 object-cover"
|
||||||
) : (
|
/>
|
||||||
<span className="text-base pl-2">
|
|
||||||
{subtitle}
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
<div className="p-4 space-y-2">
|
||||||
|
<h3 className="text-xl font-bold">{name}</h3>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
{description}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div className="clear-left text-left pl-2.5">
|
</a>
|
||||||
<p>{description}</p>
|
|
||||||
{
|
|
||||||
bullets && (
|
|
||||||
<ul>
|
|
||||||
{mapBullets()}
|
|
||||||
</ul>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
import Header from "./components/Header";
|
|
||||||
import Footer from "./components/Footer";
|
|
||||||
import Project from "./components/Project";
|
|
||||||
|
|
||||||
export default function Experience() {
|
|
||||||
return (
|
|
||||||
<div className="bg-black text-white min-h-screen">
|
|
||||||
<div className="lg:w-1/3 sm:w-full mx-auto">
|
|
||||||
<Header />
|
|
||||||
|
|
||||||
<h1 className="text-2xl font-bold my-4">Career</h1>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Project
|
|
||||||
name={"Medal.tv"}
|
|
||||||
description={"I do QA at Medal, the largest game clipping platform."}
|
|
||||||
subtitle={"2022 - Present"}
|
|
||||||
bullets={
|
|
||||||
[
|
|
||||||
"Test & ensure the product is as bug-free as humanly possible",
|
|
||||||
"Helping write tests in code & automate tedious parts of QA testing"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h1 className="text-2xl font-bold my-4">Education/Certification</h1>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Project
|
|
||||||
name={"Pembroke CSD"}
|
|
||||||
description={"Skewl is kewl (jk it just rhymes)"}
|
|
||||||
subtitle={"2013 - 2021"}
|
|
||||||
/>
|
|
||||||
<Project
|
|
||||||
name={"GVBOCES"}
|
|
||||||
description={"Skewl is kewl (jk it just rhymes)"}
|
|
||||||
subtitle={"2021 - 2022"}
|
|
||||||
/>
|
|
||||||
<Project
|
|
||||||
name={"Acellus Academy"}
|
|
||||||
description={"Skewl is kewl (jk it just rhymes)"}
|
|
||||||
subtitle={"2022 - Present"}
|
|
||||||
/>
|
|
||||||
<Project
|
|
||||||
name={"CS50"}
|
|
||||||
description={"Harvard CS50 Program"}
|
|
||||||
subtitle={"2023 - Present"}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Footer />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
+55
-16
@@ -1,33 +1,72 @@
|
|||||||
import Footer from "./components/Footer";
|
import Footer from "./components/Footer";
|
||||||
import Header from "./components/Header";
|
import Header from "./components/Header";
|
||||||
|
import ListBox from "./components/ListBox";
|
||||||
import Project from "./components/Project";
|
import Project from "./components/Project";
|
||||||
|
import ContactForm from "./components/ContactForm";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<div className="bg-black text-white min-h-screen">
|
<main className="bg-black text-white min-h-screen">
|
||||||
<div className="lg:w-1/3 sm:w-full mx-auto">
|
|
||||||
<Header />
|
<Header />
|
||||||
|
<div className="mx-auto lg:w-1/2">
|
||||||
<div className="space-y-2">
|
<section id="projects">
|
||||||
|
<div className="mb-4">
|
||||||
|
<h1 className="text-3xl font-bold">
|
||||||
|
Projects
|
||||||
|
</h1>
|
||||||
|
<p>Cool stuff I'm working on</p>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
<Project
|
<Project
|
||||||
name={"SplitStat"}
|
name="medaltv-wrapper"
|
||||||
description={"SplitStat was a Discord bot that allowed you to monitor your SplitGate stats, all from your Discord server."}
|
description="A JavaScript wrapper for the Medal.tv Developer API"
|
||||||
urlTo={"https://github.com/azpha/splitstat"}
|
urlTo="https://github.com/azpha/medaltv"
|
||||||
|
image="https://storage.alexav.gg/content/medal-logo.png"
|
||||||
/>
|
/>
|
||||||
<Project
|
<Project
|
||||||
name={"medaltv-wrapper"}
|
name="splitstat"
|
||||||
description={"A simple NodeJS wrapper for the Medal.tv Developer API"}
|
description="A Discord bot for SplitStat: Arena Warfare statistics"
|
||||||
urlTo={"https://github.com/azpha/medaltv-wrapper"}
|
urlTo="https://github.com/azpha/splitstat"
|
||||||
|
image="https://storage.alexav.gg/content/splitstat-logo.png"
|
||||||
/>
|
/>
|
||||||
<Project
|
</div>
|
||||||
name={"pmanager"}
|
</section>
|
||||||
description={"A simple self-hosted server to manage pm2 containers"}
|
<section className="bg-muted py-10 px-4">
|
||||||
urlTo={"https://github.com/azpha/pmanager"}
|
<div className="container max-w-5xl mx-auto">
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
|
<div>
|
||||||
|
<h2 className="text-3xl font-bold">About Me</h2>
|
||||||
|
<p className="text-muted-foreground mt-4">
|
||||||
|
I'm a full-stack developer with a passion for creating beautiful and functional web applications. I
|
||||||
|
have experience working with a variety of technologies, including React, Node.js, and MongoDB.
|
||||||
|
</p>
|
||||||
|
<div className="mt-8 grid grid-cols-2 gap-4">
|
||||||
|
<ListBox
|
||||||
|
title="Skills"
|
||||||
|
points={[
|
||||||
|
"JavaScript",
|
||||||
|
"Python",
|
||||||
|
"Java",
|
||||||
|
"SQL",
|
||||||
|
"Prisma"
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<ListBox
|
||||||
|
title="Experience"
|
||||||
|
points={[
|
||||||
|
"Working at Medal.tv as a QA tester",
|
||||||
|
"4 years as a JavaScript developer",
|
||||||
|
"Worked on various side-projects"
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<ContactForm />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</main>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
+1
-21
@@ -1,29 +1,9 @@
|
|||||||
import React from 'react'
|
|
||||||
import ReactDOM from 'react-dom/client'
|
import ReactDOM from 'react-dom/client'
|
||||||
import {
|
|
||||||
createBrowserRouter,
|
|
||||||
RouterProvider
|
|
||||||
} from 'react-router-dom'
|
|
||||||
import './assets/main.css'
|
import './assets/main.css'
|
||||||
|
|
||||||
// pages
|
// pages
|
||||||
import MainPage from './index';
|
import MainPage from './index';
|
||||||
import Experience from './experience';
|
|
||||||
|
|
||||||
// router
|
|
||||||
const router = createBrowserRouter([
|
|
||||||
{
|
|
||||||
path: "/",
|
|
||||||
element: <MainPage />
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "experience",
|
|
||||||
element: <Experience />
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||||
<React.StrictMode>
|
<MainPage />
|
||||||
<RouterProvider router={router} />
|
|
||||||
</React.StrictMode>,
|
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user