Skip to content

Commit

Permalink
feat: add view user sheet
Browse files Browse the repository at this point in the history
  • Loading branch information
TinsFox committed Sep 20, 2024
1 parent 5f26f9e commit 4afeb8f
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 24 deletions.
15 changes: 2 additions & 13 deletions src/hooks/query/use-user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import {
import type { PaginationState } from "@tanstack/react-table"

import { apiFetch } from "@/lib/api-fetch"
import type { ILoginForm, IUserInfo } from "@/models/user"
import type { ILoginForm, IUserProfile, IUsers } from "@/models/user"

export const queryUser = () => queryOptions({
queryKey: ["userInfo"],
queryFn: async () => apiFetch<IUserInfo>("/api/user"),
queryFn: async () => apiFetch<IUserProfile>("/api/user"),
})

export function useUser() {
Expand All @@ -36,17 +36,6 @@ export function useUserLogoutMutation() {
})
}

export interface IUsers {
id: string
amount: number
status: "pending" | "processing" | "success" | "failed"
email: string
name: string
avatar: string
createdAt: string
role: string
bio: string
}
export function useUsers(pagination: PaginationState) {
const { data } = useQuery({
queryKey: ["users", pagination.pageIndex, pagination.pageSize],
Expand Down
21 changes: 19 additions & 2 deletions src/models/user.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { z } from "zod"

export const userSchema = z.object({
export const userProfileSchema = z.object({
userId: z.string(),
avatar: z.string(),
password: z.string(),
Expand Down Expand Up @@ -31,7 +31,24 @@ export const userSchema = z.object({
.optional()
.default([]),
})
export type IUserInfo = z.infer<typeof userSchema>
export type IUserProfile = z.infer<typeof userProfileSchema>
export const userStatuses = ["pending", "processing", "success", "failed"] as const

export const userRoles = ["admin", "user", "guest"] as const

export const userSchema = z.object({
id: z.string(),
amount: z.number(),
status: z.enum(userStatuses),
email: z.string().email(),
name: z.string(),
avatar: z.string(),
createdAt: z.string(),
role: z.enum(userRoles),
bio: z.string(),
})

export type IUsers = z.infer<typeof userSchema>

export const loginFormSchema = z.object({
email: z
Expand Down
17 changes: 8 additions & 9 deletions src/pages/(admin)/(with-layout)/list/basic-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import {
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Input } from "@/components/ui/input"
Expand Down Expand Up @@ -57,8 +56,10 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table"
import type { IUsers } from "@/hooks/query/use-user"
import { useUsers } from "@/hooks/query/use-user"
import type { IUsers } from "@/models/user"

import { ViewUser } from "./components/view-user"

const columns: ColumnDef<IUsers>[] = [
{
Expand Down Expand Up @@ -158,7 +159,7 @@ const columns: ColumnDef<IUsers>[] = [
id: "actions",
enableHiding: false,
cell: ({ row }) => {
const payment = row.original
const user = row.original
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
Expand All @@ -170,13 +171,11 @@ const columns: ColumnDef<IUsers>[] = [
<DropdownMenuContent align="end">
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem
onClick={() => navigator.clipboard.writeText(payment.id)}
onClick={() => navigator.clipboard.writeText(user.id)}
>
Copy payment ID
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>View customer</DropdownMenuItem>
<DropdownMenuItem>View payment details</DropdownMenuItem>
<ViewUser user={row.original} />
</DropdownMenuContent>
</DropdownMenu>
)
Expand Down Expand Up @@ -227,8 +226,8 @@ export function Component() {
})

return (
<div className="">
<div className="flex items-center py-4">
<div className="px-2">
<div className="flex items-center py-4">
<Input
placeholder="Filter emails..."
value={(table.getColumn("email")?.getFilterValue() as string) ?? ""}
Expand Down
143 changes: 143 additions & 0 deletions src/pages/(admin)/(with-layout)/list/components/view-user.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import type { z } from "zod"

import { Button } from "@/components/ui/button"
import { DropdownMenuItem } from "@/components/ui/dropdown-menu"
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import {
Sheet,
SheetClose,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet"
import { toast } from "@/components/ui/use-toast"
import type { IUsers } from "@/models/user"
import { userRoles, userSchema } from "@/models/user"

export function ViewUser({ user }: { user: IUsers }) {
const form = useForm<IUsers>({
resolver: zodResolver(userSchema),
defaultValues: user,
})

function onSubmit(values: z.infer<typeof userSchema>) {
toast({
title: "You submitted the following values:",
description: (
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
<code className="text-white">{JSON.stringify(values, null, 2)}</code>
</pre>
),
})
}
return (
<>
<Sheet>
<SheetTrigger asChild>
<DropdownMenuItem onSelect={(event) => {
event.preventDefault()
}}
>
View customer
</DropdownMenuItem>
</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>View User</SheetTitle>
<SheetDescription>
View user details here.
</SheetDescription>
</SheetHeader>

<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<div className="grid gap-4 py-4">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
<FormLabel className="text-right">Name</FormLabel>
<FormControl className="col-span-3">
<Input {...field} placeholder="user name" />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
<FormLabel className="text-right">Email</FormLabel>
<FormControl>
<Input {...field} placeholder="[email protected]" className="col-span-3" />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="role"
render={({ field }) => (
<FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
<FormLabel className="col-span-1 text-right">Role</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger className="col-span-3">
<SelectValue placeholder="Select a role" />
</SelectTrigger>
</FormControl>
<SelectContent>
{userRoles.map((role) => (
<SelectItem key={role} value={role}>{role}</SelectItem>
))}
</SelectContent>
</Select>
</FormItem>
)}
/>
<FormField
control={form.control}
name="avatar"
render={({ field }) => (
<FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
<FormLabel className="text-right">Avatar</FormLabel>
<FormControl>
<Input {...field} placeholder="user avatar" className="col-span-3" />
</FormControl>
</FormItem>
)}
/>
</div>
</form>
</Form>
<SheetFooter>
<SheetClose asChild>
<Button type="submit">Save changes</Button>
</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet>
</>
)
}

0 comments on commit 4afeb8f

Please sign in to comment.