Skip to content

Commit

Permalink
Merge pull request #57 from K1nd4SUS/28-use-react-router-layouts
Browse files Browse the repository at this point in the history
Use react-router layouts to optimize routing
  • Loading branch information
Fraccs authored Apr 20, 2024
2 parents 36f8ce0 + d2f00f5 commit 034c2aa
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 131 deletions.
24 changes: 16 additions & 8 deletions web/frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom"
import ServicesLayout from "./layouts/ServicesLayout"
import Home from "./pages/Home"
import Service from "./pages/Service"
import Services from "./pages/Services"
Expand All @@ -22,15 +23,22 @@ export default function App() {
<Route
path="/services"
element={
<Services/>
<ServicesLayout/>
}
/>
<Route
path="/services/:nfq"
element={
<Service/>
}
/>
>
<Route
index
element={
<Services/>
}
/>
<Route
path=":nfq"
element={
<Service/>
}
/>
</Route>
</Routes>
</BrowserRouter>
)
Expand Down
14 changes: 14 additions & 0 deletions web/frontend/src/components/Error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { UseFetchError } from "../hooks/useFetch"

export type ErrorProps = {
error: UseFetchError
}

export default function Error({ error }: ErrorProps) {
return (
<div className="h-full w-full flex flex-col items-center justify-center">
<span className="font-black text-6xl text-zinc-300">Error {error.status} ({error.statusText})</span>
<p className="font-semibold text-3xl text-zinc-600">{error.data.error}.</p>
</div>
)
}
5 changes: 3 additions & 2 deletions web/frontend/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Button } from "@nextui-org/react"
import { useEffect } from "react"
import { Link } from "react-router-dom"
import { FaCheck, FaFire, FaTriangleExclamation } from "react-icons/fa6"
import cerberoPng from "../assets/images/cerbero.png"
import { useFetch } from "../hooks/useFetch"
Expand Down Expand Up @@ -35,13 +36,13 @@ export default function Header() {

return (
<header className="w-full flex items-center justify-center p-4 bg-default-50 shadow-2xl">
<a href="/services" className="absolute">
<Link to="/services" className="absolute">
<img
src={cerberoPng}
alt="cerbero"
className="h-8"
/>
</a>
</Link>
<div className="ml-auto">
{firewall?.isConnected ?
firewall?.isSynced ?
Expand Down
17 changes: 17 additions & 0 deletions web/frontend/src/components/Loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Spinner } from "@nextui-org/react"

export type LoadingProps = {
text?: string
}

export default function Loading({ text }: LoadingProps) {
return (
<div className="h-full w-full flex flex-col items-center justify-center">
<div className="flex flex-col gap-4">
<span className="font-bold text-xl">{text}</span>
<Spinner/>
</div>
</div>
)
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Card, CardBody, CardHeader, Chip, Divider, Skeleton } from "@nextui-org/react"
import { useNavigate } from "react-router-dom"
import { Link } from "react-router-dom"
import { FaCode } from "react-icons/fa6"
import { useFetchSync } from "../hooks/useFetch"
import type { CerberoRegexes } from "../types/cerbero"
Expand All @@ -12,15 +12,14 @@ export type ServiceProps = {
protocol: "tcp" | "udp"
}

export default function Service({ chain, name, nfq, port, protocol }: ServiceProps) {
const navigate = useNavigate()
export default function ServiceCard({ chain, name, nfq, port, protocol }: ServiceProps) {
const [
regexes,
isLoading
] = useFetchSync<CerberoRegexes>(`/api/regexes/${nfq}`)

return (
<div onClick={() => navigate(`/services/${nfq}`)}>
<Link to={`/services/${nfq}`}>
<Card key={nfq} className="h-full w-full text-zinc-300 hover:scale-[102.5%] hover:cursor-pointer">
<CardHeader className="w-full flex items-center">
<div className="flex flex-col gap-1 px-2">
Expand Down Expand Up @@ -60,6 +59,6 @@ export default function Service({ chain, name, nfq, port, protocol }: ServicePro
</div>
</CardBody>
</Card>
</div>
</Link>
)
}
13 changes: 5 additions & 8 deletions web/frontend/src/components/ServiceRegexesList.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Button, Input, Spinner, Tab, Tabs, Tooltip } from "@nextui-org/react"
import { Button, Input, Tab, Tabs, Tooltip } from "@nextui-org/react"
import { useEffect, useState } from "react"
import { FaArrowLeft, FaArrowRight, FaTrash } from "react-icons/fa6"
import Error from "../components/Error"
import Loading from "../components/Loading"
import { useFetch } from "../hooks/useFetch"
import { CerberoRegexes } from "../types/cerbero"
import { hexEncode } from "../utils/regexes"
Expand Down Expand Up @@ -89,18 +91,13 @@ export default function ServiceRegexesList({ nfq }: ServiceRegexesListProps) {

if(isRegexesLoading) {
return (
<div className="h-full w-full flex flex-col items-center justify-center">
<Spinner/>
</div>
<Loading text="Loading regexes..."/>
)
}

if(regexesError) {
return (
<div className="h-full w-full flex flex-col items-center justify-center">
<span className="font-black text-xl text-zinc-300">{regexesError.status} ({regexesError.statusText})</span>
<span className="font-semibold text-zinc-600">{regexesError.data.error}</span>
</div>
<Error error={regexesError}/>
)
}

Expand Down
24 changes: 14 additions & 10 deletions web/frontend/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Button, Divider } from "@nextui-org/react"
import { motion } from "framer-motion"
import { useState } from "react"
import { Link, useNavigate } from "react-router-dom"
import { Link } from "react-router-dom"
import { FaBars, FaCode, FaHouse } from "react-icons/fa6"
import SidebarItem from "../components/SidebarItem"
import { useFetchSync } from "../hooks/useFetch"
import { CerberoService } from "../types/cerbero"
import SidebarItem from "./SidebarItem"

export default function Sidebar() {
const [
Expand All @@ -14,7 +14,6 @@ export default function Sidebar() {
] = useFetchSync<CerberoService[]>("/api/services")

const [isOpen, setIsOpen] = useState(false)
const navigate = useNavigate()

return (
<motion.aside
Expand Down Expand Up @@ -51,14 +50,19 @@ export default function Sidebar() {
</div>
<div className="w-full flex items-center justify-center">
{isOpen ?
<Button variant="bordered" className="w-full flex items-center gap-4" onPress={() => navigate("/")}>
<FaHouse/>
<span>Go to the landing page</span>
</Button> :
<Button isIconOnly={true} variant="bordered" onPress={() => navigate("/")}>
<FaHouse/>
</Button>}
<Link to="/" className="w-full flex items-center gap-4">
<Button variant="bordered" className="w-full">
<FaHouse/>
<span>Go to the landing page</span>
</Button>
</Link> :
<Link to="/">
<Button isIconOnly={true} variant="bordered">
<FaHouse/>
</Button>
</Link>}
</div>
</motion.aside>
)
}

17 changes: 10 additions & 7 deletions web/frontend/src/components/SidebarItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Button, Link, Tooltip } from "@nextui-org/react"
import { Button, Tooltip } from "@nextui-org/react"
import { ReactNode, useState } from "react"
import { Link } from "react-router-dom"
import { FaCaretDown, FaCaretUp } from "react-icons/fa6"

export type SidebarItemProps = {
Expand All @@ -15,18 +16,20 @@ export default function SidebarItem({ children, icon, isSidebarOpen, link, name

if(!isSidebarOpen) {
return (
<Tooltip content="Services" size="sm" delay={1000}>
<Button as={Link} href={link} isIconOnly={true} variant="bordered" size="sm">
{icon}
</Button>
</Tooltip>
<Link to={link}>
<Tooltip content="Services" size="sm" delay={1000}>
<Button isIconOnly={true} variant="bordered" size="sm">
{icon}
</Button>
</Tooltip>
</Link>
)
}

return (
<div className="w-full flex flex-col gap-2">
<div className="flex items-center">
<Link color="foreground" href={link} className="flex items-center gap-2">
<Link color="foreground" to={link} className="flex items-center gap-2">
{icon}
<span className="font-bold">{name}</span>
</Link>
Expand Down
16 changes: 16 additions & 0 deletions web/frontend/src/layouts/ServicesLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Outlet } from "react-router-dom"
import Header from "../components/Header"
import Main from "./Main"
import Page from "./Page"

export default function ServicesLayout() {
return (
<Page>
<Header/>
<Main>
<Outlet/>
</Main>
</Page>
)
}

24 changes: 0 additions & 24 deletions web/frontend/src/pages/Loading.tsx

This file was deleted.

85 changes: 41 additions & 44 deletions web/frontend/src/pages/Service.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { Card, CardBody, Chip } from "@nextui-org/react"
import { useEffect } from "react"
import { useParams } from "react-router-dom"
import Header from "../components/Header"
import Error from "../components/Error"
import Loading from "../components/Loading"
import ServiceRegexesList from "../components/ServiceRegexesList"
import { useFetchSync } from "../hooks/useFetch"
import Main from "../layouts/Main"
import Page from "../layouts/Page"
import { useFetch } from "../hooks/useFetch"
import type { CerberoService } from "../types/cerbero"
import Error from "./Error"
import Loading from "./Loading"

export default function Service() {
const { nfq } = useParams()
const [
service,
fetchService,
isLoading,
error
] = useFetchSync<CerberoService>(`/api/services/${nfq}`)
] = useFetch<CerberoService>()

useEffect(() => {
void fetchService(`/api/services/${nfq}`)
}, [nfq])

if(error) {
return (
Expand All @@ -25,49 +28,43 @@ export default function Service() {

if(isLoading) {
return (
<Loading
text="Loading service"
/>
<Loading text="Loading service..."/>
)
}

return (
<Page>
<Header/>
<Main>
<div className="h-full w-full flex flex-col">
<div className="flex justify-between p-8">
<div className="flex flex-col gap-2 p-8 border-b-2 border-zinc-700">
<div className="flex flex-col gap-4 md:flex-row md:items-center">
<span className="font-black text-5xl">{service?.name}</span>
<Chip variant="flat" color="success">
<span className="font-mono text-lg">{service?.protocol}://vm:{service?.port}</span>
</Chip>
<Chip variant="flat" color="primary">
<span className="font-mono text-lg">chain:{service?.chain}</span>
</Chip>
</div>
<span className="font-mono text-3xl text-zinc-300">nfq:{service?.nfq}</span>
</div>
<div className="h-full w-full flex flex-col">
<div className="flex justify-between p-8">
<div className="flex flex-col gap-2 p-8 border-b-2 border-zinc-700">
<div className="flex flex-col gap-4 md:flex-row md:items-center">
<span className="font-black text-5xl">{service?.name}</span>
<Chip variant="flat" color="success">
<span className="font-mono text-lg">{service?.protocol}://vm:{service?.port}</span>
</Chip>
<Chip variant="flat" color="primary">
<span className="font-mono text-lg">chain:{service?.chain}</span>
</Chip>
</div>
<div className="h-full flex flex-col gap-4 p-4 md:flex-row">
<div className="flex-1 flex flex-col gap-4 p-4">
<span className="font-bold text-3xl text-zinc-300">Metrics</span>
<div className="h-full w-full flex flex-col items-center justify-center bg-default-100 rounded-xl">
<span className="font-thin text-xl italic">Placeholder</span>
</div>
</div>
<div className="flex-1 flex flex-col gap-4 p-4">
<span className="font-bold text-3xl text-zinc-300">Regexes</span>
<Card className="h-full bg-default-100">
<CardBody>
<ServiceRegexesList nfq={nfq as string}/>
</CardBody>
</Card>
</div>
<span className="font-mono text-3xl text-zinc-300">nfq:{service?.nfq}</span>
</div>
</div>
<div className="h-full flex flex-col gap-4 p-4 md:flex-row">
<div className="flex-1 flex flex-col gap-4 p-4">
<span className="font-bold text-3xl text-zinc-300">Metrics</span>
<div className="h-full w-full flex flex-col items-center justify-center bg-default-100 rounded-xl">
<span className="font-thin text-xl italic">Placeholder</span>
</div>
</div>
</Main>
</Page>
<div className="flex-1 flex flex-col gap-4 p-4">
<span className="font-bold text-3xl text-zinc-300">Regexes</span>
<Card className="h-full bg-default-100">
<CardBody>
<ServiceRegexesList nfq={nfq as string}/>
</CardBody>
</Card>
</div>
</div>
</div>
)
}

Loading

0 comments on commit 034c2aa

Please sign in to comment.