Main page / CORS

This commit is contained in:
Leons Aleksandrovs
2025-07-02 21:18:08 +03:00
parent ebc0665468
commit 95afdcb364
9 changed files with 80 additions and 5 deletions

View File

@@ -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()

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>;
}

View 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
View File

@@ -0,0 +1 @@
export const API_BASE_URL = "http://127.0.0.1:8000";

View File

@@ -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>
);
}

View File

@@ -1,5 +1,11 @@
@import "tailwindcss";
@theme {
--color-accent: #123ffb;
--color-body: #dfe1e5;
--color-panel: white;
}
body {
@apply m-0;
font-family:

View File

@@ -0,0 +1,3 @@
export interface User {
username: string;
}