diff --git a/orval.config.ts b/orval.config.ts index 1b551c3..1f81720 100644 --- a/orval.config.ts +++ b/orval.config.ts @@ -1,10 +1,19 @@ import { defineConfig } from "orval"; import dotenv from "dotenv"; +/** + * See https://orval.dev/ + */ + dotenv.config(); const baseUrl = process.env.BADGEHUB_API_BASEURL || "https://api-staging.badgehub.nl"; + +const swaggerUrl = `${baseUrl}/swagger.json`; + +console.log("Reading swagger from", swaggerUrl); + export default defineConfig({ badgehub: { output: { @@ -22,7 +31,7 @@ export default defineConfig({ }, input: { - target: `${baseUrl}/swagger.json`, + target: swaggerUrl, }, }, }); diff --git a/package-lock.json b/package-lock.json index f5556bf..b7d6017 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "clsx": "^2.1.1", "eslint": "^8.57.1", "eslint-config-next": "^14.2.15", + "jose": "^5.9.4", "jsonpath-plus": "^10.1.0", "orval": "^7.0.1", "prettier": "3.3.3", @@ -4834,9 +4835,10 @@ } }, "node_modules/jose": { - "version": "4.15.9", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", - "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "version": "5.9.6", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.9.6.tgz", + "integrity": "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -5338,6 +5340,15 @@ } } }, + "node_modules/next-auth/node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/nimma": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/nimma/-/nimma-0.2.3.tgz", @@ -5748,6 +5759,15 @@ "url": "https://github.com/sponsors/panva" } }, + "node_modules/openid-client/node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", diff --git a/package.json b/package.json index 03fc034..fc873a3 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "eslint": "^8.57.1", "eslint-config-next": "^14.2.15", "jsonpath-plus": "^10.1.0", + "jose": "^5.9.4", "orval": "^7.0.1", "prettier": "3.3.3", "typescript": "^5" diff --git a/src/app/actions.ts b/src/app/actions.ts index 3cb6927..c983bee 100644 --- a/src/app/actions.ts +++ b/src/app/actions.ts @@ -1,10 +1,22 @@ +"use server"; + import { GetAppsParams } from "@/badgehub-api-client/generated/models"; import { - getDevices, - getCategories, getApps, + getCategories, + getDevices, } from "@/badgehub-api-client/generated/swagger/public/public"; -export async function getAppData(searchParams: GetAppsParams) { - return Promise.all([getApps(searchParams), getCategories(), getDevices()]); +export async function getAppData(searchParams: GetAppsParams, token: string) { + const headers = new Headers({ + Authorization: `Bearer ${token}`, + }); + const options: RequestInit = { + headers, + }; + return Promise.all([ + getApps(searchParams, options), + getCategories(options), + getDevices(options), + ]); } diff --git a/src/app/apps/layout.tsx b/src/app/apps/layout.tsx index 4287dd1..f9d3028 100644 --- a/src/app/apps/layout.tsx +++ b/src/app/apps/layout.tsx @@ -1,11 +1,20 @@ -import { ReactNode } from "react"; +"use client"; + +import { SessionProvider } from "next-auth/react"; import styles from "./layout.module.css"; +import { ReactNode } from "react"; + +type AppsListingLayoutProps = { + children: ReactNode; +}; -export default function AppsListingLayout(props: { children: ReactNode }) { +export default function AppsListingLayout({ + children, +}: AppsListingLayoutProps) { return (

Apps

- {props.children} + {children}
); } diff --git a/src/app/apps/page.tsx b/src/app/apps/page.tsx index 4e7655d..6af9364 100644 --- a/src/app/apps/page.tsx +++ b/src/app/apps/page.tsx @@ -1,5 +1,14 @@ +"use client"; + import { AppList } from "@/components/AppList"; +import { SessionProvider, useSession } from "next-auth/react"; import { LoginButton } from "@/components/LoginButton"; +import { useEffect, useState } from "react"; +import { + getAppsResponse, + getCategoriesResponse, + getDevicesResponse, +} from "@/badgehub-api-client/generated/swagger/public/public"; import { getAppData } from "../actions"; export interface SearchParams { @@ -7,33 +16,30 @@ export interface SearchParams { device: string; } -export default async function Listing({ +export default function Listing({ searchParams, }: { searchParams: Partial; }) { - let data; - try { - // TODO add caching - data = await getAppData(searchParams); - } catch (e) { - if (!(e instanceof Error)) { - return

Caught object that wasn&t an error.

; + const { data: session } = useSession(); + const [data, setData] = useState< + [getAppsResponse, getCategoriesResponse, getDevicesResponse] | null + >(null); + + useEffect(() => { + async function getData() { + const token = (session as any)?.accessToken; + const data = await getAppData(searchParams, token); + setData(data); } - return ( - <> -

Error while rendering

- -
{JSON.stringify(e.message)}
-
- - ); - } + + getData(); + }, [searchParams, session]); return ( <> - + {data ? :

Loading new data...

} ); } diff --git a/src/badgehub-api-client/generated/models/app.ts b/src/badgehub-api-client/generated/models/app.ts new file mode 100644 index 0000000..b636277 --- /dev/null +++ b/src/badgehub-api-client/generated/models/app.ts @@ -0,0 +1,14 @@ +/** + * Generated by orval v7.1.1 🍺 + * Do not edit manually. + * badgehub-api + * Node project for the BadgeHub API + * OpenAPI spec version: 3 + */ + +export interface App { + category_slug: string; + name: string; + slug: string; + user_name: string; +} diff --git a/src/badgehub-api-client/generated/models/appDetails.ts b/src/badgehub-api-client/generated/models/appDetails.ts new file mode 100644 index 0000000..ae64f5a --- /dev/null +++ b/src/badgehub-api-client/generated/models/appDetails.ts @@ -0,0 +1,16 @@ +/** + * Generated by orval v7.1.1 🍺 + * Do not edit manually. + * badgehub-api + * Node project for the BadgeHub API + * OpenAPI spec version: 3 + */ + +export interface AppDetails { + category_slug: string; + description: string; + devices: string[]; + name: string; + slug: string; + user_name: string; +} diff --git a/src/badgehub-api-client/generated/models/device.ts b/src/badgehub-api-client/generated/models/device.ts new file mode 100644 index 0000000..3ea9b80 --- /dev/null +++ b/src/badgehub-api-client/generated/models/device.ts @@ -0,0 +1,12 @@ +/** + * Generated by orval v7.1.1 🍺 + * Do not edit manually. + * badgehub-api + * Node project for the BadgeHub API + * OpenAPI spec version: 3 + */ + +export interface Device { + name: string; + slug: string; +} diff --git a/src/badgehub-api-client/generated/models/getAppDetails404.ts b/src/badgehub-api-client/generated/models/getAppDetails404.ts new file mode 100644 index 0000000..a0dd5eb --- /dev/null +++ b/src/badgehub-api-client/generated/models/getAppDetails404.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v7.1.1 🍺 + * Do not edit manually. + * badgehub-api + * Node project for the BadgeHub API + * OpenAPI spec version: 3 + */ + +export type GetAppDetails404 = { + reason: string; +}; diff --git a/src/badgehub-api-client/generated/models/index.ts b/src/badgehub-api-client/generated/models/index.ts index 068e34f..c31296f 100644 --- a/src/badgehub-api-client/generated/models/index.ts +++ b/src/badgehub-api-client/generated/models/index.ts @@ -6,7 +6,9 @@ * OpenAPI spec version: 3 */ +export * from './app'; export * from './appCategoryName'; +export * from './appDetails'; export * from './appMetadataJSON'; export * from './appMetadataJSONFileMappingsItem'; export * from './badge'; @@ -14,8 +16,10 @@ export * from './category'; export * from './dbInsertAppMetadataJSONPartial'; export * from './dbInsertAppMetadataJSONPartialFileMappingsItem'; export * from './dependency'; +export * from './device'; export * from './fileMetadata'; export * from './getApp404'; +export * from './getAppDetails404'; export * from './getAppsParams'; export * from './pickDBInsertProjectExcludeKeyofDBInsertProjectSlug'; export * from './pickDBInsertUserExcludeKeyofDBInsertUserId'; diff --git a/src/badgehub-api-client/generated/swagger/private/private.ts b/src/badgehub-api-client/generated/swagger/private/private.ts index 6a62450..8e5053c 100644 --- a/src/badgehub-api-client/generated/swagger/private/private.ts +++ b/src/badgehub-api-client/generated/swagger/private/private.ts @@ -12,7 +12,6 @@ import type { ProjectSlug, Uint8Array, UserProps, - Version, WriteFileBody } from '../../models' import { fetchWithBaseUrl } from '../../../../fetch-from-api'; @@ -243,7 +242,7 @@ export const changeAppMetadata = async (slug: string, * Upload a file to the latest draft version of the project. */ export type writeZipResponse = { - data: Version; + data: void; status: number; } diff --git a/src/components/Account/index.tsx b/src/components/Account/index.tsx index 4214885..c412449 100644 --- a/src/components/Account/index.tsx +++ b/src/components/Account/index.tsx @@ -20,6 +20,7 @@ export function Account() { return ( <>

Account

+

JWT: {(session as any)?.accessToken}

{html} ); diff --git a/src/components/Filter/index.tsx b/src/components/Filter/index.tsx index 4e570ce..344dbd3 100644 --- a/src/components/Filter/index.tsx +++ b/src/components/Filter/index.tsx @@ -3,11 +3,11 @@ import styles from "./Filter.module.css"; import { useRef } from "react"; import { useSearchParams, useRouter } from "next/navigation"; -import { Category, Badge } from "@/badgehub-api-client/generated/models"; +import { Category, Device } from "@/badgehub-api-client/generated/models"; type FilterProps = { categories: Category[]; - devices: Badge[]; + devices: Device[]; }; export function Filter({ categories, devices }: FilterProps) { diff --git a/src/components/MainNav/index.tsx b/src/components/MainNav/index.tsx index 704454c..e4e0044 100644 --- a/src/components/MainNav/index.tsx +++ b/src/components/MainNav/index.tsx @@ -7,8 +7,6 @@ import clsx from "clsx"; export function MainNav() { const pathname = usePathname(); - console.log("pathname", pathname); - return (