From 399b2656b8af879f930c294ecba4ab57e60cc4f4 Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Fri, 3 Apr 2026 13:40:06 +0530 Subject: [PATCH] profile view --- src_generic/App.tsx | 3 ++ src_generic/components/AdminLayout.tsx | 13 ++++-- src_generic/components/ProfileView.tsx | 58 ++++++++++++++++++++++++++ src_generic/configuration.ts | 5 +++ src_generic/hooks/useResource.ts | 12 ++++++ src_generic/types/config.ts | 4 ++ src_generic/utils/openapi_loader.ts | 5 ++- 7 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 src_generic/components/ProfileView.tsx diff --git a/src_generic/App.tsx b/src_generic/App.tsx index 076730c..8430a48 100644 --- a/src_generic/App.tsx +++ b/src_generic/App.tsx @@ -64,6 +64,8 @@ function Dashboard() { ); } +import ProfileView from "./components/ProfileView"; + function AdminApp() { const { currentUser, login, logout, loading, error } = useAuth(); const config = React.useContext(ConfigContext); @@ -93,6 +95,7 @@ function AdminApp() { > } /> + } /> } /> } /> } /> diff --git a/src_generic/components/AdminLayout.tsx b/src_generic/components/AdminLayout.tsx index bc717d8..db66af2 100644 --- a/src_generic/components/AdminLayout.tsx +++ b/src_generic/components/AdminLayout.tsx @@ -12,6 +12,7 @@ import { ListItemIcon, ListItemText, CssBaseline, + Button, IconButton, Tooltip, useMediaQuery, @@ -176,9 +177,15 @@ export default function AdminLayout({ Admin Panel - - {username} - + + + diff --git a/src_generic/components/ProfileView.tsx b/src_generic/components/ProfileView.tsx new file mode 100644 index 0000000..0134d0e --- /dev/null +++ b/src_generic/components/ProfileView.tsx @@ -0,0 +1,58 @@ +import * as React from 'react'; +import { Box, Typography, Paper, CircularProgress, Alert } from '@mui/material'; +import { useResource } from '../hooks/useResource'; +import GenericForm from './GenericForm'; +import { ConfigContext } from '../App'; + +export default function ProfileView() { + const appConfig = React.useContext(ConfigContext); + const profileConfig = appConfig?.profile; + const resourceConfig = appConfig?.resources.find(r => r.name === profileConfig?.resource); + + if (!profileConfig || !resourceConfig) { + debugger; + return Profile configuration not found.; + } + + const { useMe, useUpdate } = useResource(resourceConfig); + const { data: profile, isLoading, error } = useMe(); + const updateMutation = useUpdate(); + + const handleSave = async (formData: any) => { + try { + const id = profile[resourceConfig.primaryKey]; + await updateMutation.mutateAsync({ id, data: formData }); + } catch (err) { + console.error('Profile update failed:', err); + } + }; + + if (isLoading) { + return ( + + + + ); + } + + if (error) { + return Failed to load profile data.; + } + + return ( + + + My Profile + + + window.history.back()} + loading={updateMutation.isPending} + /> + + + ); +} diff --git a/src_generic/configuration.ts b/src_generic/configuration.ts index c22d2cd..f436f12 100644 --- a/src_generic/configuration.ts +++ b/src_generic/configuration.ts @@ -40,3 +40,8 @@ export const configuration: Record = { }, }, }; + +export const profileConfiguration = { + "extraFields": ['name'], + "resource": "payors" +}; diff --git a/src_generic/hooks/useResource.ts b/src_generic/hooks/useResource.ts index 2fad529..b722ac5 100644 --- a/src_generic/hooks/useResource.ts +++ b/src_generic/hooks/useResource.ts @@ -81,9 +81,21 @@ export function useResource(config: ResourceConfig) { }, }); + // --- READ ME --- + const useMe = () => + useQuery({ + queryKey: [name, "me"], + queryFn: async () => { + // @ts-ignore + const res = await api.get(`${endpoint}/me`); + return res.data; + }, + }); + return { useList, useRead, + useMe, useCreate, useUpdate, useDelete, diff --git a/src_generic/types/config.ts b/src_generic/types/config.ts index 4b7b59b..ded62d9 100644 --- a/src_generic/types/config.ts +++ b/src_generic/types/config.ts @@ -35,4 +35,8 @@ export interface AppConfig { baseUrl: string; authBaseUrl: string; resources: ResourceConfig[]; + profile?: { + resource: string; + extraFields?: Record; + }; } diff --git a/src_generic/utils/openapi_loader.ts b/src_generic/utils/openapi_loader.ts index f12fd61..d06aa61 100644 --- a/src_generic/utils/openapi_loader.ts +++ b/src_generic/utils/openapi_loader.ts @@ -1,6 +1,6 @@ import SwaggerParser from "@apidevtools/swagger-parser"; import { AppConfig, ResourceConfig, ResourceField, FieldType } from "../types/config"; -import { configuration } from "../configuration"; +import { configuration, profileConfiguration } from "../configuration"; /** * Maps OpenAPI property types to our internal FieldType @@ -115,7 +115,7 @@ export async function loadConfigFromOpenApi(baseUrl: string): Promise resourcePaths[base].methods.push(...methods); // Identify the list endpoint for this resource - if (!path.includes("{") && paths[path]?.get?.responses?.["200"]) { + if (!resourcePaths[base].listPath && !path.includes("{") && paths[path]?.get?.responses?.["200"]) { resourcePaths[base].listPath = path; } } @@ -170,5 +170,6 @@ export async function loadConfigFromOpenApi(baseUrl: string): Promise baseUrl: serverBaseUrl, authBaseUrl: authBaseUrl, resources, + profile: profileConfiguration, }; }