Main page / CORS
This commit is contained in:
@@ -1,10 +1,20 @@
|
||||
from fastapi import FastAPI
|
||||
import sqlite3
|
||||
from db.users import get_users, get_attendance
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
# Get fastapi app
|
||||
app = FastAPI()
|
||||
|
||||
# Add cors headers to the app
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["http://localhost:3000", "http://127.0.0.1:3000"],
|
||||
allow_credentials=True,
|
||||
allow_methods=["GET"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
@app.get("/")
|
||||
def list_users():
|
||||
return get_users()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<title>Bolderjara Serviss</title>
|
||||
</head>
|
||||
<body class="bg-gray-900">
|
||||
<body class="bg-body">
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Link } from "@tanstack/react-router";
|
||||
|
||||
export default function Header() {
|
||||
return (
|
||||
<header className="flex gap-4 p-4 bg-gray-800 font-bold text-gray-100">
|
||||
<nav className="">
|
||||
<header className="flex gap-4 p-4 bg-panel shadow font-bold">
|
||||
<nav className="text-accent">
|
||||
<Link to="/">Home</Link>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export default function MainContainer(props: { children: React.ReactNode; className?: string }) {
|
||||
return <main className={`max-w-4xl mx-auto ${props.className || ""}`}>{props.children}</main>;
|
||||
return <main className={`max-w-4xl px-4 mx-auto ${props.className || ""}`}>{props.children}</main>;
|
||||
}
|
||||
|
||||
53
frontend/src/components/UsersTable.tsx
Normal file
53
frontend/src/components/UsersTable.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { API_BASE_URL } from "@/consts";
|
||||
import type { User } from "@/types/api";
|
||||
import { useQuery, type UseQueryResult } from "@tanstack/react-query";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
function RenderList({ list }: { list: UseQueryResult<User[]> }) {
|
||||
// Base classes for each row
|
||||
const baseRowClass = "text-xl p-2 px-4 rounded capitalize bg-panel/75";
|
||||
|
||||
// Display loading and error states
|
||||
if (list.isLoading) return <div className={`${baseRowClass} text-gray-400`}>Loading...</div>;
|
||||
if (list.isError) return <div className={`${baseRowClass} text-red-400`}>Error: {list.error.message}</div>;
|
||||
|
||||
// Render all users to the list
|
||||
return list.data?.map((u) => {
|
||||
return (
|
||||
<p className={`${baseRowClass} transition cursor-pointer hover:bg-panel hover:text-accent`}>{u.username}</p>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export default function UsersTable() {
|
||||
// UseState for search input
|
||||
const [search, setSearch] = useState(""); // For input control
|
||||
const [debouncedSearch, setDebouncedSearch] = useState(search); // For when user stops typing, do refetching
|
||||
|
||||
// Build search query url
|
||||
const fetchUsersURL = new URL(`${API_BASE_URL}/`);
|
||||
if (search) fetchUsersURL.searchParams.set("s", search);
|
||||
|
||||
// Using tanstack query to fetch, and automatically cache the data
|
||||
const fetchUsers = () => fetch(fetchUsersURL).then((res) => res.json());
|
||||
const users = useQuery<User[]>({ queryKey: ["users", debouncedSearch], queryFn: fetchUsers });
|
||||
|
||||
// Use effect is being used to make refetch after user has stopped typing in the search bar
|
||||
useEffect(() => {
|
||||
const timeout = setTimeout(() => setDebouncedSearch(search), 500);
|
||||
return () => clearTimeout(timeout); // Clear timeout
|
||||
}, [search]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<input
|
||||
placeholder="Search users"
|
||||
className="bg-panel/75 transition focus:bg-panel border border-transparent outline-none focus:border-accent rounded px-4 py-2 mt-8 w-full "
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
/>
|
||||
<ul className="space-y-2 mt-2">
|
||||
<RenderList list={users} />
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
1
frontend/src/consts.ts
Normal file
1
frontend/src/consts.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const API_BASE_URL = "http://127.0.0.1:8000";
|
||||
@@ -1,5 +1,6 @@
|
||||
import MainContainer from "@/components/MainContainer";
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import UsersTable from "@/components/UsersTable";
|
||||
|
||||
export const Route = createFileRoute("/")({
|
||||
component: App,
|
||||
@@ -8,7 +9,8 @@ export const Route = createFileRoute("/")({
|
||||
function App() {
|
||||
return (
|
||||
<MainContainer className="pt-8">
|
||||
<h1 className="text-4xl font-bold text-center text-gray-100">Darbinieki</h1>
|
||||
<h1 className="text-4xl font-bold text-center text-accent">Darbinieki</h1>
|
||||
<UsersTable />
|
||||
</MainContainer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
@theme {
|
||||
--color-accent: #123ffb;
|
||||
--color-body: #dfe1e5;
|
||||
--color-panel: white;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply m-0;
|
||||
font-family:
|
||||
|
||||
3
frontend/src/types/api.ts
Normal file
3
frontend/src/types/api.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface User {
|
||||
username: string;
|
||||
}
|
||||
Reference in New Issue
Block a user