mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-07-01 03:05:55 +00:00
Refactor dashboard components and update global styles
- Updated the title and description in layout.tsx to reflect the new application name. - Replaced the background color in globals.css with a background image for the title section. - Enhanced the Devices and UserDevices pages by adding search and filter components for improved user interaction. - Introduced a new DevicesTable component for displaying device data with pagination. - Updated the Users page to improve layout and added a filter for user status. - Made various UI adjustments across components for better consistency and usability.
This commit is contained in:
@ -5,10 +5,10 @@ import Link from "next/link";
|
||||
|
||||
import { signup } from "@/actions/auth-actions";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Loader } from "lucide-react";
|
||||
import { useActionState } from "react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import type { Island, Prisma } from "@prisma/client";
|
||||
import { Loader } from "lucide-react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { useActionState } from "react";
|
||||
import * as React from "react";
|
||||
|
||||
import {
|
||||
@ -20,6 +20,7 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Checkbox } from "../ui/checkbox";
|
||||
|
||||
type AtollWithIslands = Prisma.AtollGetPayload<{
|
||||
include: {
|
||||
@ -31,13 +32,16 @@ export default function SignUpForm({ atolls }: { atolls: AtollWithIslands[] }) {
|
||||
const [atoll, setAtoll] = React.useState<AtollWithIslands>();
|
||||
const [islands, setIslands] = React.useState<Island[]>();
|
||||
|
||||
const [actionState, action, isPending] = useActionState(signup, {
|
||||
message: "",
|
||||
});
|
||||
|
||||
|
||||
React.useEffect(() => {
|
||||
setIslands(atoll?.islands);
|
||||
}, [atoll]);
|
||||
|
||||
const [actionState, action, isPending] = useActionState(signup, {
|
||||
message: "",
|
||||
});
|
||||
|
||||
const params = useSearchParams();
|
||||
const phoneNumberFromUrl = params.get("phone_number");
|
||||
const NUMBER_WITHOUT_DASH = phoneNumberFromUrl?.split("-").join("");
|
||||
@ -83,7 +87,7 @@ export default function SignUpForm({ atolls }: { atolls: AtollWithIslands[] }) {
|
||||
className={cn(
|
||||
"text-base",
|
||||
actionState.errors?.fieldErrors?.id_card &&
|
||||
"border-2 border-red-500",
|
||||
"border-2 border-red-500",
|
||||
)}
|
||||
placeholder="ID Card"
|
||||
/>
|
||||
@ -160,26 +164,26 @@ export default function SignUpForm({ atolls }: { atolls: AtollWithIslands[] }) {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="house_name" className="text-sm">
|
||||
House Name
|
||||
<label htmlFor="address" className="text-sm">
|
||||
Address
|
||||
</label>
|
||||
<Input
|
||||
className={cn(
|
||||
"text-base",
|
||||
actionState.errors?.fieldErrors?.house_name &&
|
||||
"border-2 border-red-500",
|
||||
actionState.errors?.fieldErrors?.address &&
|
||||
"border-2 border-red-500",
|
||||
)}
|
||||
disabled={isPending}
|
||||
name="house_name"
|
||||
name="address"
|
||||
defaultValue={
|
||||
(actionState.payload?.get("house_name") || "") as string
|
||||
(actionState.payload?.get("address") || "") as string
|
||||
}
|
||||
type="text"
|
||||
placeholder="House Name"
|
||||
placeholder="Address"
|
||||
/>
|
||||
{actionState.errors?.fieldErrors?.house_name && (
|
||||
{actionState.errors?.fieldErrors?.address && (
|
||||
<span className="text-sm inline-block text-red-500">
|
||||
{actionState.errors?.fieldErrors?.house_name}
|
||||
{actionState.errors?.fieldErrors?.address}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@ -217,8 +221,8 @@ export default function SignUpForm({ atolls }: { atolls: AtollWithIslands[] }) {
|
||||
disabled={isPending}
|
||||
className={cn(
|
||||
!phoneNumberFromUrl &&
|
||||
actionState.errors?.fieldErrors?.phone_number &&
|
||||
"border-2 border-red-500 rounded-md",
|
||||
actionState.errors?.fieldErrors?.phone_number &&
|
||||
"border-2 border-red-500 rounded-md",
|
||||
)}
|
||||
defaultValue={NUMBER_WITHOUT_DASH ?? ""}
|
||||
readOnly={Boolean(phoneNumberFromUrl)}
|
||||
@ -235,6 +239,51 @@ export default function SignUpForm({ atolls }: { atolls: AtollWithIslands[] }) {
|
||||
{actionState.message}
|
||||
</span>
|
||||
)}
|
||||
<div className="flex flex-col gap-2 items-start justify-start py-2">
|
||||
<div className="flex gap-2 items-center">
|
||||
<Checkbox
|
||||
defaultChecked={(actionState.payload?.get("terms") || "") as string === 'on'}
|
||||
name="terms" id="terms" />
|
||||
<label
|
||||
htmlFor="terms"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
<span>
|
||||
i accept
|
||||
</span>
|
||||
<Link className="ml-1 underline" href="">
|
||||
terms and conditions
|
||||
</Link>
|
||||
</label>
|
||||
</div>
|
||||
{actionState.errors?.fieldErrors?.terms && (
|
||||
<span className="text-sm inline-block text-red-500">
|
||||
{actionState.errors?.fieldErrors?.terms}
|
||||
</span>
|
||||
)}
|
||||
<div className="flex gap-2 items-center">
|
||||
|
||||
<Checkbox
|
||||
name="policy" id="terms" />
|
||||
<label
|
||||
htmlFor="terms"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
<span>
|
||||
i undertand
|
||||
</span>
|
||||
<Link className="ml-1 underline" href="">
|
||||
the privacy policy
|
||||
</Link>
|
||||
</label>
|
||||
</div>
|
||||
{actionState.errors?.fieldErrors?.policy && (
|
||||
<span className="text-sm inline-block text-red-500">
|
||||
{actionState.errors?.fieldErrors?.policy}
|
||||
</span>
|
||||
)}
|
||||
|
||||
</div>
|
||||
<Button disabled={isPending} className="mt-4 w-full" type="submit">
|
||||
{isPending ? <Loader className="animate-spin" /> : "Submit"}
|
||||
</Button>
|
||||
|
Reference in New Issue
Block a user