Implement new features and enhance existing components for improved user experience

- Added a new `bun.lockb` file for dependency management.
- Updated `next.config.ts` to set output to "standalone" for better deployment options.
- Removed `package-lock.json` to streamline package management.
- Modified `package.json` to update dependencies, including `@prisma/client` and `sonner`, and adjusted build scripts for improved functionality.
- Enhanced Tailwind CSS configuration to include new animations and color schemes.
- Refactored various dashboard components to improve UI consistency, including adding a new `My Wallet` page and updating existing pages to use a unified styling approach.
- Introduced a new `BlockDeviceDialog` component for managing device blocking with user-defined reasons.
- Improved logging and error handling in payment verification and device management functions.

These changes enhance the overall functionality, maintainability, and user experience of the application.
This commit is contained in:
2024-12-26 20:25:38 +05:00
parent 5fb6f52bfc
commit bdf3729b0d
25 changed files with 299 additions and 10198 deletions

View File

@ -1,35 +1,135 @@
'use client'
"use client"
import { blockDevice } from "@/actions/omada-actions";
import { Button } from "@/components/ui/button";
import type { Device } from "@prisma/client";
import { useState } from "react";
import { toast } from "sonner";
import { TextShimmer } from "./ui/text-shimmer";
import { blockDevice } from "@/actions/omada-actions"
import { Button } from "@/components/ui/button"
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import { Label } from "@/components/ui/label"
import { cn } from "@/lib/utils"
import { zodResolver } from "@hookform/resolvers/zod"
import type { Device, } from "@prisma/client"
import { OctagonX } from "lucide-react"
import { useState } from "react"
import { type SubmitHandler, useForm } from "react-hook-form"
import { toast } from "sonner"
import { z } from "zod"
import { Textarea } from "./ui/textarea"
import { TextShimmer } from "./ui/text-shimmer"
const validationSchema = z.object({
reasonForBlocking: z.string().min(5, { message: "Reason is required" }),
})
export default function BlockDeviceDialog({ device, type }: { device: Device, type: "block" | "unblock" }) {
const [disabled, setDisabled] = useState(false)
const [open, setOpen] = useState(false)
const {
register,
handleSubmit,
formState: { errors },
} = useForm<z.infer<typeof validationSchema>>({
resolver: zodResolver(validationSchema),
})
const onSubmit: SubmitHandler<z.infer<typeof validationSchema>> = (data) => {
setDisabled(true)
console.log(data)
toast.promise(blockDevice({
macAddress: device.mac,
type: type,
reason: data.reasonForBlocking,
// reason: data.reasonForBlocking,
}), {
loading: "Blocking...",
success: () => {
setDisabled(false)
setOpen((prev) => !prev)
return "Blocked!"
},
error: (error) => {
setDisabled(false)
return error || "Something went wrong"
},
})
setDisabled(false)
}
export default function BlockDeviceDialog({ device }: { device: Device }) {
const [disabled, setDisabled] = useState(false);
return (
<Button
className="w-full mt-2"
disabled={disabled}
onClick={() => {
setDisabled(true);
toast.promise(blockDevice({ macAddress: device.mac, type: device.blocked ? "unblock" : "block" }), {
loading: device.blocked ? "Unblocking..." : "Blocking...",
success: () => {
setDisabled(false);
return `Device ${device.name} successfully ${device.blocked ? "unblocked" : "blocked"
}!`;
},
error: () => {
setDisabled(false);
return "Something went wrong";
},
});
}}
>
{disabled ? <TextShimmer>{device.blocked ? "Unblocking..." : "Blocking..."}</TextShimmer> : (device?.blocked ? "Unblock" : "Block")}
</Button>
<div>
{device.blocked ? (
<Button onClick={
() => {
setDisabled(true);
toast.promise(blockDevice({
macAddress: device.mac,
type: "unblock",
reason: '',
}), {
loading: "unblockinig...",
success: () => {
setDisabled(false);
return "Unblocked!";
},
error: () => {
setDisabled(false);
return "Something went wrong";
},
})
}
}>
{disabled ? (
<TextShimmer>
Unblocking
</TextShimmer>
) : "Unblock"}
</Button>
) : (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button disabled={disabled} variant="destructive">
<OctagonX />
Block
</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>Please provide a reason for blocking this device.</DialogTitle>
</DialogHeader>
<form onSubmit={handleSubmit(onSubmit)}>
<div className="grid gap-4 py-4">
<div className="flex flex-col items-start gap-1">
<Label htmlFor="reason" className="text-right">
Reason for blocking
</Label>
<Textarea rows={10} {...register("reasonForBlocking")} id="reasonForBlocking" className={cn("col-span-5", errors.reasonForBlocking && "ring-2 ring-red-500")} />
<span className="text-sm text-red-500">
{errors.reasonForBlocking?.message}
</span>
</div>
</div>
<DialogFooter>
<Button variant={"destructive"} disabled={disabled} type="submit">
Block
</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
)}
</div>
)
}