Data Access Layer #13

Merged
guus merged 4 commits from add-data-layer into master 2025-07-28 20:11:09 +02:00
5 changed files with 33 additions and 19 deletions
Showing only changes of commit 7c92b33f91 - Show all commits
+1
View File
@@ -7,3 +7,4 @@ albums/
wallpapers/ wallpapers/
frontend/node_modules/ frontend/node_modules/
frontend/.next/ frontend/.next/
frontend/src/data/types.ts
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
if [ -z "$1" ]; then
set -- "BACKEND_HOST"
fi
HOST=$(grep "$1" .env 2>/dev/null | cut -d '=' -f 2 | tr -d '"')
echo $1
echo $HOST
cmd="npx openapi-typescript $HOST/api/schema/ -o src/data/types.tmp.ts"
if eval $cmd
then
echo $cmd
mv src/data/types.tmp.ts src/data/types.ts
fi
chmod go+rw src/data/types.ts
+4 -3
View File
@@ -9,10 +9,11 @@
"react-oidc-context": "^3.3.0" "react-oidc-context": "^3.3.0"
}, },
"scripts": { "scripts": {
"dev": "next dev", "dev": "npm run generate:types && next dev",
"build": "next build", "build": "npm run generate:types && next build",
"start": "next start", "start": "next start",
"lint": "next lint" "lint": "next lint",
"generate:types": "bash generate_types.sh DOCKER_BACKEND"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/postcss": "^4.1.10", "@tailwindcss/postcss": "^4.1.10",
+3 -3
View File
@@ -1,10 +1,10 @@
"use client"; "use client";
import { getUser } from "muzak/data/fetch"; import { getUser } from "muzak/data/fetch";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import api from "muzak/data/fetcher"; import { api, User } from "muzak/data/fetcher";
export default function Page() { export default function Page() {
const [userData, setUserData] = useState([]); const [userData, setUserData] = useState<User[]>([]);
useEffect(() => { useEffect(() => {
async function getUsers() { async function getUsers() {
@@ -17,7 +17,7 @@ export default function Page() {
return ( return (
<div className="flex min-h-screen flex-col items-center justify-around"> <div className="flex min-h-screen flex-col items-center justify-around">
{userData.length > 0 ? ( {userData.length > 0 ? (
userData.map((user) => <div key={user.id}>{user.email}</div>) userData.map((user: User) => <div key={user.id}>{user.email}</div>)
) : ( ) : (
<div>Loading users...</div> <div>Loading users...</div>
)} )}
+9 -13
View File
@@ -1,13 +1,9 @@
"use client"; "use client";
import { Fetcher } from "openapi-typescript-fetch"; import { Fetcher } from "openapi-typescript-fetch";
import { getUser } from "./fetch"; import { getUser } from "./fetch";
import { paths, components } from "muzak/data/types";
interface GenericPaths { const fetcher = Fetcher.for<paths>();
[path: string]: {
[method: string]: any;
};
}
const fetcher = Fetcher.for<GenericPaths>();
const BASE_URL = process.env.BACKEND_HOST || "http://127.0.0.1:8001"; const BASE_URL = process.env.BACKEND_HOST || "http://127.0.0.1:8001";
// Configure the fetcher // Configure the fetcher
@@ -19,7 +15,7 @@ fetcher.configure({
}, },
}, },
use: [ use: [
// Authentication middleware // Add authentication token to request
async (url, init, next) => { async (url, init, next) => {
const user = getUser(); const user = getUser();
if (user?.access_token) { if (user?.access_token) {
@@ -30,18 +26,14 @@ fetcher.configure({
} }
return next(url, init); return next(url, init);
}, },
// Error handling middleware // Handle errors
async (url, init, next) => { async (url, init, next) => {
const response = await next(url, init); const response = await next(url, init);
if (!response.ok) { if (!response.ok) {
// Handle authentication errors
if (response.status === 401) { if (response.status === 401) {
console.warn("Authentication failed - token may be expired"); console.warn("Authentication failed - token may be expired");
// You might want to trigger a redirect to login or token refresh here
} }
// Log other errors
console.error(`API Error: ${response.status} ${response.statusText}`, { console.error(`API Error: ${response.status} ${response.statusText}`, {
url, url,
method: init.method, method: init.method,
@@ -53,7 +45,6 @@ fetcher.configure({
], ],
}); });
// Create your API methods
export const api = { export const api = {
tracks: { tracks: {
list: fetcher.path("/api/track/").method("get").create(), list: fetcher.path("/api/track/").method("get").create(),
@@ -88,4 +79,9 @@ export const api = {
}, },
}; };
export type User = components["schemas"]["User"];
export type Track = components["schemas"]["Track"];
export type Album = components["schemas"]["Album"];
export type Vote = components["schemas"]["Vote"];
export default api; export default api;