Update API documentation and UI to improve clarity and add role-based access control.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 705f2157-ef97-4fbd-89e4-8c7f2ecaea90
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7ed01c5f-a82d-405a-b728-b2e3d127c60c/994ee92d-6a6d-4ca4-99c0-fe0dbc7f160b.jpg
This commit is contained in:
alphaeusmote
2025-04-08 02:23:25 +00:00
parent 58f8360240
commit a872feecd2
17 changed files with 1666 additions and 106 deletions
@@ -15,50 +15,50 @@ export default function ApiDocumentationCard() {
<Button
variant="link"
className="p-0 h-auto font-medium text-sm text-primary"
onClick={() => window.open("/api/docs", "_blank")}
onClick={() => window.open("/api-docs", "_blank")}
>
View Full Documentation
</Button>
</CardHeader>
<CardContent className="p-4">
<div className="bg-muted rounded-md p-4 font-mono text-sm overflow-x-auto">
<pre className="text-xs whitespace-pre-wrap">
# Active Directory Management API
<div className="text-xs whitespace-pre-wrap">
<p className="font-bold mb-2"># Active Directory Management API</p>
## User Endpoints
<p className="font-bold mt-3 mb-2">## User Endpoints</p>
GET /api/users
- Query Parameters:
- filter: Filter users by property values (e.g. ?filter=name eq 'John')
- select: Select specific properties to return (e.g. ?select=id,name,email)
- expand: Include related entities (e.g. ?expand=groups)
- orderBy: Order results (e.g. ?orderBy=name asc)
- top: Limit number of results (e.g. ?top=10)
- skip: Skip number of results (e.g. ?skip=10)
<p className="mb-1">GET /api/users</p>
<p className="mb-1">- Query Parameters:</p>
<p className="ml-4 mb-1">- filter: Filter users by property values (e.g. ?filter=name eq 'John')</p>
<p className="ml-4 mb-1">- select: Select specific properties to return (e.g. ?select=id,name,email)</p>
<p className="ml-4 mb-1">- expand: Include related entities (e.g. ?expand=groups)</p>
<p className="ml-4 mb-1">- orderBy: Order results (e.g. ?orderBy=name asc)</p>
<p className="ml-4 mb-1">- top: Limit number of results (e.g. ?top=10)</p>
<p className="ml-4 mb-1">- skip: Skip number of results (e.g. ?skip=10)</p>
POST /api/users
- Create a new user in Active Directory
- Request body: User object
<p className="mt-3 mb-1">POST /api/users</p>
<p className="mb-1">- Create a new user in Active Directory</p>
<p className="mb-1">- Request body: User object</p>
GET /api/users/{id}
- Get a specific user by ID
- Query Parameters:
- select: Select specific properties to return
<p className="mt-3 mb-1">GET /api/users/{"{userId}"}</p>
<p className="mb-1">- Get a specific user by ID</p>
<p className="mb-1">- Query Parameters:</p>
<p className="ml-4 mb-1">- select: Select specific properties to return</p>
PUT /api/users/{id}
- Update a specific user
- Request body: User object with updated properties
<p className="mt-3 mb-1">PUT /api/users/{"{userId}"}</p>
<p className="mb-1">- Update a specific user</p>
<p className="mb-1">- Request body: User object with updated properties</p>
DELETE /api/users/{id}
- Delete a specific user
</pre>
<p className="mt-3 mb-1">DELETE /api/users/{"{userId}"}</p>
<p className="mb-1">- Delete a specific user</p>
</div>
</div>
<div className="mt-4 flex justify-end">
<Button
variant="link"
className="p-0 h-auto font-medium text-sm text-primary"
onClick={() => window.open("/api/docs", "_blank")}
onClick={() => window.open("/api-docs", "_blank")}
>
Go to Swagger Documentation <ArrowRight className="ml-1 h-4 w-4" />
</Button>
+10
View File
@@ -2,6 +2,16 @@
@tailwind components;
@tailwind utilities;
@layer components {
.drawer-item {
@apply text-gray-700 hover:bg-gray-100 hover:text-primary focus:outline-none transition-colors duration-200;
}
.drawer-item.active {
@apply bg-primary/10 text-primary font-medium;
}
}
@layer base {
:root {
--background: 0 0% 96%;
+19 -20
View File
@@ -160,22 +160,21 @@ export function DashboardLayout({ children, title, description }: DashboardLayou
} ${isMobile ? "absolute" : "relative"}`}
>
<div className="h-16 flex items-center px-4 border-b">
<Link href="/">
<a className="font-medium text-lg text-primary">AD Management API</a>
<Link href="/" className="font-medium text-lg text-primary">
AD Management API
</Link>
</div>
<div className="overflow-y-auto h-[calc(100%-64px)]">
<div className="px-2 pt-4">
<Link href="/">
<a
className={`drawer-item px-4 py-2 flex items-center space-x-3 rounded cursor-pointer ${
location === "/" ? "active" : ""
}`}
>
<Home className="h-4 w-4" />
<span>Dashboard</span>
</a>
<Link
href="/"
className={`drawer-item px-4 py-2 flex items-center space-x-3 rounded cursor-pointer ${
location === "/" ? "active" : ""
}`}
>
<Home className="h-4 w-4" />
<span>Dashboard</span>
</Link>
{menuSections.map((section, idx) => (
@@ -185,15 +184,15 @@ export function DashboardLayout({ children, title, description }: DashboardLayou
</div>
{section.items.map((item, itemIdx) => (
<Link href={item.path} key={itemIdx}>
<a
className={`drawer-item px-4 py-2 flex items-center space-x-3 rounded cursor-pointer ${
location === item.path ? "active" : ""
}`}
>
{item.icon}
<span>{item.title}</span>
</a>
<Link
href={item.path}
key={itemIdx}
className={`drawer-item px-4 py-2 flex items-center space-x-3 rounded cursor-pointer ${
location === item.path ? "active" : ""
}`}
>
{item.icon}
<span>{item.title}</span>
</Link>
))}
</div>
+3 -1
View File
@@ -42,6 +42,8 @@ const registerSchema = insertUserSchema.extend({
acceptTerms: z.boolean().refine(val => val === true, {
message: "You must accept the terms and conditions",
}),
// Define roleId explicitly to match form values
roleId: z.number().optional().nullable(),
}).refine(data => data.password === data.confirmPassword, {
message: "Passwords do not match",
path: ["confirmPassword"],
@@ -140,7 +142,7 @@ export default function AuthPage() {
email: "",
fullName: "",
acceptTerms: false,
role: "user",
roleId: 2, // Assign the default "user" role ID
},
});