mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-04-19 20:56:52 +00:00
TEMPORARY FIX TO TEST BUILD
Some checks failed
Build and Push Docker Images / Build and Push Docker Images (push) Failing after 1m15s
Some checks failed
Build and Push Docker Images / Build and Push Docker Images (push) Failing after 1m15s
This commit is contained in:
parent
e8296ae3f6
commit
b932fcf03c
@ -1,6 +1,4 @@
|
||||
import SignUpForm from "@/components/auth/signup-form";
|
||||
import type { ApiResponse, Atoll, Island } from "@/lib/backend-types";
|
||||
import { getAtolls } from "@/queries/islands";
|
||||
import Image from "next/image";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
@ -9,18 +7,23 @@ export default async function SignupPage({
|
||||
}: {
|
||||
searchParams: Promise<{ phone_number: string }>;
|
||||
}) {
|
||||
|
||||
const phone_number = (await searchParams).phone_number;
|
||||
console.log({ phone_number })
|
||||
console.log({ phone_number });
|
||||
if (!phone_number) {
|
||||
return redirect("/auth/login");
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="dark:bg-black w-full h-screen flex items-center justify-center font-sans">
|
||||
<div className="flex flex-col items-center justify-center w-full h-full ">
|
||||
<Image priority alt="Sar Link Logo" src="/logo.png" width={100} height={100} style={{ width: "auto", height: "auto" }} />
|
||||
<Image
|
||||
priority
|
||||
alt="Sar Link Logo"
|
||||
src="/logo.png"
|
||||
width={100}
|
||||
height={100}
|
||||
style={{ width: "auto", height: "auto" }}
|
||||
/>
|
||||
<div className="mt-4 flex flex-col items-center justify-center">
|
||||
<h4 className="font-bold text-xl text-gray-600">SAR Link Portal</h4>
|
||||
<p className="text-gray-500">
|
||||
|
@ -2,10 +2,8 @@ import { getPayment } from "@/actions/payment";
|
||||
import { authOptions } from "@/app/auth";
|
||||
import CancelPaymentButton from "@/components/billing/cancel-payment-button";
|
||||
import DevicesToPay from "@/components/devices-to-pay";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { tryCatch } from "@/utils/tryCatch";
|
||||
import { Trash2 } from "lucide-react";
|
||||
import { getServerSession } from "next-auth";
|
||||
export default async function PaymentPage({
|
||||
params,
|
||||
|
@ -1,11 +1,3 @@
|
||||
import InputReadOnly from "@/components/input-read-only";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import UserRejectDialog from "@/components/user/user-reject-dialog";
|
||||
import { UserVerifyDialog } from "@/components/user/user-verify-dialog";
|
||||
import { getNationalPerson } from "@/lib/person";
|
||||
|
||||
import Image from "next/image";
|
||||
|
||||
export default async function VerifyUserPage({
|
||||
params,
|
||||
}: {
|
||||
@ -14,6 +6,7 @@ export default async function VerifyUserPage({
|
||||
}>;
|
||||
}) {
|
||||
const userId = (await params).userId;
|
||||
console.log("userId", userId);
|
||||
// const dbUser = await prisma.user.findUnique({
|
||||
// where: {
|
||||
// id: userId,
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { Rejectuser } from "@/actions/user-actions";
|
||||
import Filter from "@/components/filter";
|
||||
import Search from "@/components/search";
|
||||
import { UsersTable } from "@/components/user-table";
|
||||
@ -9,8 +8,7 @@ import {
|
||||
Hourglass,
|
||||
Minus,
|
||||
} from "lucide-react";
|
||||
import { redirect } from "next/navigation";
|
||||
import React, { Suspense } from "react";
|
||||
import { Suspense } from "react";
|
||||
|
||||
const sortfilterOptions = [
|
||||
{
|
||||
|
@ -1,10 +1,5 @@
|
||||
import { blockDevice } from "@/actions/omada-actions";
|
||||
import { validateApiKey } from "@/lib/utils";
|
||||
import { addDays, addMonths, isAfter, isWithinInterval } from "date-fns";
|
||||
|
||||
const lastRunTime = new Date();
|
||||
|
||||
export async function GET(request: Request) {
|
||||
console.log(request.url);
|
||||
return Response.json({ message: "Request received" });
|
||||
// try {
|
||||
// // Validate API key before proceeding
|
||||
|
6
app/next-auth.d.ts
vendored
6
app/next-auth.d.ts
vendored
@ -1,5 +1,7 @@
|
||||
import NextAuth, { DefaultSession, type User } from "next-auth";
|
||||
import { Session } from "next-auth";
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
// @ts-expect-error importing unused types are required here
|
||||
import NextAuth, { DefaultSession, type User, Session } from "next-auth";
|
||||
/* eslint-enable @typescript-eslint/no-unused-vars */
|
||||
declare module "next-auth" {
|
||||
/**
|
||||
* Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
|
||||
|
@ -1,18 +1,18 @@
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCaption,
|
||||
TableCell,
|
||||
TableFooter,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { headers } from "next/headers";
|
||||
import Link from "next/link";
|
||||
import BlockDeviceDialog from "../block-device-dialog";
|
||||
import DeviceCard from "../device-card";
|
||||
import Pagination from "../pagination";
|
||||
// import {
|
||||
// Table,
|
||||
// TableBody,
|
||||
// TableCaption,
|
||||
// TableCell,
|
||||
// TableFooter,
|
||||
// TableHead,
|
||||
// TableHeader,
|
||||
// TableRow,
|
||||
// } from "@/components/ui/table";
|
||||
// import { headers } from "next/headers";
|
||||
// import Link from "next/link";
|
||||
// import BlockDeviceDialog from "../block-device-dialog";
|
||||
// import DeviceCard from "../device-card";
|
||||
// import Pagination from "../pagination";
|
||||
|
||||
export async function AdminDevicesTable({
|
||||
searchParams,
|
||||
@ -25,12 +25,14 @@ export async function AdminDevicesTable({
|
||||
}>;
|
||||
parentalControl?: boolean;
|
||||
}) {
|
||||
console.log(parentalControl);
|
||||
// const session = await auth.api.getSession({
|
||||
// headers: await headers(),
|
||||
// });
|
||||
// const isAdmin = session?.user.role === "ADMIN";
|
||||
// const query = (await searchParams)?.query || "";
|
||||
// const page = (await searchParams)?.page;
|
||||
const query = (await searchParams)?.query || "";
|
||||
const page = (await searchParams)?.page;
|
||||
console.log(query, page);
|
||||
// const sortBy = (await searchParams)?.sortBy || "asc";
|
||||
// const totalDevices = await prisma.device.count({
|
||||
// where: {
|
||||
|
@ -1,17 +1,17 @@
|
||||
import Pagination from "@/components/pagination";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCaption,
|
||||
TableCell,
|
||||
TableFooter,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import Link from "next/link";
|
||||
// import Pagination from "@/components/pagination";
|
||||
// import { Badge } from "@/components/ui/badge";
|
||||
// import { Button } from "@/components/ui/button";
|
||||
// import {
|
||||
// Table,
|
||||
// TableBody,
|
||||
// TableCaption,
|
||||
// TableCell,
|
||||
// TableFooter,
|
||||
// TableHead,
|
||||
// TableHeader,
|
||||
// TableRow,
|
||||
// } from "@/components/ui/table";
|
||||
// import Link from "next/link";
|
||||
|
||||
export async function UsersPaymentsTable({
|
||||
searchParams,
|
||||
@ -24,8 +24,9 @@ export async function UsersPaymentsTable({
|
||||
}>;
|
||||
}) {
|
||||
const query = (await searchParams)?.query || "";
|
||||
const page = (await searchParams)?.page;
|
||||
const sortBy = (await searchParams)?.sortBy || "asc";
|
||||
console.log(query);
|
||||
// const page = (await searchParams)?.page;
|
||||
// const sortBy = (await searchParams)?.sortBy || "asc";
|
||||
// const totalPayments = await prisma.payment.count({
|
||||
// where: {
|
||||
// OR: [
|
||||
|
@ -7,13 +7,11 @@ import {
|
||||
} from "@/components/ui/popover";
|
||||
import { Loader2, User as UserIcon } from "lucide-react";
|
||||
import { signOut, useSession } from "next-auth/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
|
||||
export function AccountPopover() {
|
||||
const session = useSession();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
if (session.status === "loading") {
|
||||
<Button variant={"outline"} disabled>
|
||||
|
@ -23,7 +23,7 @@ import { getAtolls } from "@/queries/islands";
|
||||
import { keepPreviousData, useQuery } from "@tanstack/react-query";
|
||||
|
||||
export default function SignUpForm() {
|
||||
const { data: atolls, isFetching } = useQuery<ApiResponse<Atoll>>({
|
||||
const { data: atolls } = useQuery<ApiResponse<Atoll>>({
|
||||
queryKey: ["ATOLLS"],
|
||||
queryFn: () => getAtolls(),
|
||||
placeholderData: keepPreviousData,
|
||||
|
@ -17,7 +17,8 @@ export default function CancelPaymentButton({
|
||||
<Button
|
||||
onClick={async () => {
|
||||
setLoading(true);
|
||||
const [error, _] = await tryCatch(cancelPayment({ id: paymentId }));
|
||||
const [error, x] = await tryCatch(cancelPayment({ id: paymentId }));
|
||||
console.log(x);
|
||||
if (error) {
|
||||
toast.error(error.message);
|
||||
setLoading(false);
|
||||
|
@ -3,7 +3,6 @@ import { TableCell, TableRow } from "@/components/ui/table";
|
||||
import { deviceCartAtom } from "@/lib/atoms";
|
||||
import type { Device } from "@/lib/backend-types";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { pl } from "date-fns/locale";
|
||||
import { useAtom } from "jotai";
|
||||
import { Hourglass } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
@ -5,18 +5,16 @@ import DeviceCard from "@/components/device-card";
|
||||
import NumberInput from "@/components/number-input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { deviceCartAtom, numberOfMonths } from "@/lib/atoms";
|
||||
import type { NewPayment, Payment } from "@/lib/backend-types";
|
||||
import type { NewPayment } from "@/lib/backend-types";
|
||||
import { tryCatch } from "@/utils/tryCatch";
|
||||
import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
||||
import { CircleDollarSign, Loader2 } from "lucide-react";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { redirect, usePathname } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
export default function DevicesForPayment() {
|
||||
const baseAmount = 100;
|
||||
const discountPercentage = 75;
|
||||
const session = useSession();
|
||||
const pathname = usePathname();
|
||||
const devices = useAtomValue(deviceCartAtom);
|
||||
const setDeviceCart = useSetAtom(deviceCartAtom);
|
||||
@ -24,6 +22,7 @@ export default function DevicesForPayment() {
|
||||
const [message, setMessage] = useState("");
|
||||
const [disabled, setDisabled] = useState(false);
|
||||
const [total, setTotal] = useState(0);
|
||||
console.log(total);
|
||||
useEffect(() => {
|
||||
if (months === 7) {
|
||||
setMessage("You will get 1 month free.");
|
||||
|
@ -35,7 +35,7 @@ export async function DevicesTable({
|
||||
if (error) {
|
||||
return <pre>{JSON.stringify(error, null, 2)}</pre>;
|
||||
}
|
||||
const { meta, links, data } = devices;
|
||||
const { meta, data } = devices;
|
||||
return (
|
||||
<div>
|
||||
{data.length === 0 ? (
|
||||
|
@ -9,7 +9,6 @@ import {
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import type { Payment } from "@/lib/backend-types";
|
||||
import { formatDate } from "@/lib/utils";
|
||||
import {
|
||||
BadgeDollarSign,
|
||||
Clipboard,
|
||||
@ -26,6 +25,7 @@ export default function DevicesToPay({
|
||||
payment,
|
||||
user,
|
||||
}: { payment?: Payment; user?: User }) {
|
||||
console.log(user);
|
||||
const [verifying, setVerifying] = useState(false);
|
||||
|
||||
const devices = payment?.devices;
|
||||
|
@ -93,7 +93,7 @@ export async function PaymentsTable({
|
||||
return <pre>{JSON.stringify(error, null, 2)}</pre>;
|
||||
}
|
||||
}
|
||||
const { data, meta, links } = payments;
|
||||
const { data, meta } = payments;
|
||||
return (
|
||||
<div>
|
||||
{data?.length === 0 ? (
|
||||
|
@ -55,7 +55,6 @@ type Categories = {
|
||||
}[];
|
||||
|
||||
export async function AppSidebar({
|
||||
role,
|
||||
...props
|
||||
}: React.ComponentProps<typeof Sidebar>) {
|
||||
const categories = [
|
||||
|
@ -1,71 +1,72 @@
|
||||
"use client"
|
||||
"use client";
|
||||
|
||||
import { ChevronLeft, ChevronRight } from "lucide-react"
|
||||
import { DayPicker } from "react-day-picker"
|
||||
import { ChevronLeft, ChevronRight } from "lucide-react";
|
||||
import { DayPicker } from "react-day-picker";
|
||||
|
||||
import { buttonVariants } from "@/components/ui/button"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export type CalendarProps = React.ComponentProps<typeof DayPicker>
|
||||
export type CalendarProps = React.ComponentProps<typeof DayPicker>;
|
||||
|
||||
function Calendar({
|
||||
className,
|
||||
classNames,
|
||||
showOutsideDays = true,
|
||||
...props
|
||||
className,
|
||||
classNames,
|
||||
showOutsideDays = true,
|
||||
...props
|
||||
}: CalendarProps) {
|
||||
return (
|
||||
<DayPicker
|
||||
showOutsideDays={showOutsideDays}
|
||||
className={cn("p-3", className)}
|
||||
classNames={{
|
||||
months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
|
||||
month: "space-y-4",
|
||||
caption: "flex justify-center pt-1 relative items-center",
|
||||
caption_label: "text-sm font-medium",
|
||||
nav: "space-x-1 flex items-center",
|
||||
nav_button: cn(
|
||||
buttonVariants({ variant: "outline" }),
|
||||
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
|
||||
),
|
||||
nav_button_previous: "absolute left-1",
|
||||
nav_button_next: "absolute right-1",
|
||||
table: "w-full border-collapse space-y-1",
|
||||
head_row: "flex",
|
||||
head_cell:
|
||||
"text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]",
|
||||
row: "flex w-full mt-2",
|
||||
cell: cn(
|
||||
"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md",
|
||||
props.mode === "range"
|
||||
? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md"
|
||||
: "[&:has([aria-selected])]:rounded-md"
|
||||
),
|
||||
day: cn(
|
||||
buttonVariants({ variant: "ghost" }),
|
||||
"h-8 w-8 p-0 font-normal aria-selected:opacity-100"
|
||||
),
|
||||
day_range_start: "day-range-start",
|
||||
day_range_end: "day-range-end",
|
||||
day_selected:
|
||||
"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
|
||||
day_today: "bg-accent text-accent-foreground",
|
||||
day_outside:
|
||||
"day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground",
|
||||
day_disabled: "text-muted-foreground opacity-50",
|
||||
day_range_middle:
|
||||
"aria-selected:bg-accent aria-selected:text-accent-foreground",
|
||||
day_hidden: "invisible",
|
||||
...classNames,
|
||||
}}
|
||||
components={{
|
||||
IconLeft: () => <ChevronLeft className="h-4 w-4" />,
|
||||
IconRight: () => <ChevronRight className="h-4 w-4" />,
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
return (
|
||||
<DayPicker
|
||||
showOutsideDays={showOutsideDays}
|
||||
className={cn("p-3", className)}
|
||||
classNames={{
|
||||
months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
|
||||
month: "space-y-4",
|
||||
caption: "flex justify-center pt-1 relative items-center",
|
||||
caption_label: "text-sm font-medium",
|
||||
nav: "space-x-1 flex items-center",
|
||||
nav_button: cn(
|
||||
buttonVariants({ variant: "outline" }),
|
||||
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
|
||||
),
|
||||
nav_button_previous: "absolute left-1",
|
||||
nav_button_next: "absolute right-1",
|
||||
table: "w-full border-collapse space-y-1",
|
||||
head_row: "flex",
|
||||
head_cell:
|
||||
"text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]",
|
||||
row: "flex w-full mt-2",
|
||||
cell: cn(
|
||||
"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md",
|
||||
props.mode === "range"
|
||||
? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md"
|
||||
: "[&:has([aria-selected])]:rounded-md",
|
||||
),
|
||||
day: cn(
|
||||
buttonVariants({ variant: "ghost" }),
|
||||
"h-8 w-8 p-0 font-normal aria-selected:opacity-100",
|
||||
),
|
||||
day_range_start: "day-range-start",
|
||||
day_range_end: "day-range-end",
|
||||
day_selected:
|
||||
"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
|
||||
day_today: "bg-accent text-accent-foreground",
|
||||
day_outside:
|
||||
"day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground",
|
||||
day_disabled: "text-muted-foreground opacity-50",
|
||||
day_range_middle:
|
||||
"aria-selected:bg-accent aria-selected:text-accent-foreground",
|
||||
day_hidden: "invisible",
|
||||
...classNames,
|
||||
}}
|
||||
components={{
|
||||
// @ts-expect-error this works but types are not correct
|
||||
IconLeft: () => <ChevronLeft className="h-4 w-4" />,
|
||||
IconRight: () => <ChevronRight className="h-4 w-4" />,
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Calendar.displayName = "Calendar"
|
||||
Calendar.displayName = "Calendar";
|
||||
|
||||
export { Calendar }
|
||||
export { Calendar };
|
||||
|
@ -1,17 +1,17 @@
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCaption,
|
||||
TableCell,
|
||||
TableFooter,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import Link from "next/link";
|
||||
import Pagination from "./pagination";
|
||||
import { Badge } from "./ui/badge";
|
||||
import { Button } from "./ui/button";
|
||||
// import {
|
||||
// Table,
|
||||
// TableBody,
|
||||
// TableCaption,
|
||||
// TableCell,
|
||||
// TableFooter,
|
||||
// TableHead,
|
||||
// TableHeader,
|
||||
// TableRow,
|
||||
// } from "@/components/ui/table";
|
||||
// import Link from "next/link";
|
||||
// import Pagination from "./pagination";
|
||||
// import { Badge } from "./ui/badge";
|
||||
// import { Button } from "./ui/button";
|
||||
|
||||
export async function UsersTable({
|
||||
searchParams,
|
||||
@ -24,9 +24,10 @@ export async function UsersTable({
|
||||
}>;
|
||||
}) {
|
||||
const query = (await searchParams)?.query || "";
|
||||
const page = (await searchParams)?.page;
|
||||
const sortBy = (await searchParams)?.sortBy || "asc";
|
||||
const verified = (await searchParams)?.status || "all";
|
||||
console.log(query);
|
||||
// const page = (await searchParams)?.page;
|
||||
// const sortBy = (await searchParams)?.sortBy || "asc";
|
||||
// const verified = (await searchParams)?.status || "all";
|
||||
// const totalUsers = await prisma.user.count({
|
||||
// where: {
|
||||
// OR: [
|
||||
|
@ -62,6 +62,7 @@ export default function AddDeviceDialogForm({ user_id }: { user_id?: string }) {
|
||||
toast.error(error.message || "Something went wrong.");
|
||||
setDisabled(false);
|
||||
} else {
|
||||
console.log(response);
|
||||
setOpen(false);
|
||||
setDisabled(false);
|
||||
toast.success("Device successfully added!");
|
||||
|
@ -1,7 +1,7 @@
|
||||
"use client"
|
||||
"use client";
|
||||
|
||||
import { Rejectuser } from "@/actions/user-actions"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Rejectuser } from "@/actions/user-actions";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@ -10,56 +10,56 @@ import {
|
||||
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 { User } from "@prisma/client"
|
||||
import { UserX } 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"
|
||||
|
||||
|
||||
} from "@/components/ui/dialog";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import type { User } from "@/lib/types/user";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { UserX } 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";
|
||||
|
||||
const validationSchema = z.object({
|
||||
reason: z.string().min(5, { message: "Reason is required" }),
|
||||
})
|
||||
});
|
||||
|
||||
export default function UserRejectDialog({ user }: { user: User }) {
|
||||
const [disabled, setDisabled] = useState(false)
|
||||
const [open, setOpen] = useState(false)
|
||||
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(Rejectuser({
|
||||
userId: user.id,
|
||||
reason: data.reason,
|
||||
}), {
|
||||
loading: "Rejecting...",
|
||||
success: () => {
|
||||
setDisabled(false)
|
||||
setOpen((prev) => !prev)
|
||||
return "Rejected!"
|
||||
setDisabled(true);
|
||||
console.log(data);
|
||||
toast.promise(
|
||||
Rejectuser({
|
||||
userId: String(user.id),
|
||||
reason: data.reason,
|
||||
}),
|
||||
{
|
||||
loading: "Rejecting...",
|
||||
success: () => {
|
||||
setDisabled(false);
|
||||
setOpen((prev) => !prev);
|
||||
return "Rejected!";
|
||||
},
|
||||
error: (error) => {
|
||||
setDisabled(false);
|
||||
return error.message || "Something went wrong";
|
||||
},
|
||||
},
|
||||
error: (error) => {
|
||||
setDisabled(false)
|
||||
return error.message || "Something went wrong"
|
||||
},
|
||||
})
|
||||
setDisabled(false)
|
||||
|
||||
}
|
||||
);
|
||||
setDisabled(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
@ -71,20 +71,25 @@ export default function UserRejectDialog({ user }: { user: User }) {
|
||||
</DialogTrigger>
|
||||
<DialogContent className="sm:max-w-[425px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Are you sure you want to {" "}
|
||||
<span className="text-red-500">reject</span>{" "}
|
||||
this user?</DialogTitle>
|
||||
<DialogTitle>
|
||||
Are you sure you want to{" "}
|
||||
<span className="text-red-500">reject</span> this user?
|
||||
</DialogTitle>
|
||||
<DialogDescription className="py-2">
|
||||
<li>Name: {user.name}</li>
|
||||
<li>
|
||||
Name: {user.first_name} {user.last_name}
|
||||
</li>
|
||||
<li>ID Card: {user.id_card}</li>
|
||||
<li>Address: {user.address}</li>
|
||||
<li>DOB: {new Date(user.dob ?? "").toLocaleDateString("en-US", {
|
||||
month: "short",
|
||||
day: "2-digit",
|
||||
year: "numeric",
|
||||
})}
|
||||
<li>
|
||||
DOB:{" "}
|
||||
{new Date(user.dob ?? "").toLocaleDateString("en-US", {
|
||||
month: "short",
|
||||
day: "2-digit",
|
||||
year: "numeric",
|
||||
})}
|
||||
</li>
|
||||
<li>Phone Number: {user.phoneNumber}</li>
|
||||
<li>Phone Number: {user.mobile}</li>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
@ -93,7 +98,15 @@ export default function UserRejectDialog({ user }: { user: User }) {
|
||||
<Label htmlFor="reason" className="text-right">
|
||||
Rejection details
|
||||
</Label>
|
||||
<Textarea rows={10} {...register("reason")} id="reason" className={cn("col-span-5", errors.reason && "ring-2 ring-red-500")} />
|
||||
<Textarea
|
||||
rows={10}
|
||||
{...register("reason")}
|
||||
id="reason"
|
||||
className={cn(
|
||||
"col-span-5",
|
||||
errors.reason && "ring-2 ring-red-500",
|
||||
)}
|
||||
/>
|
||||
<span className="text-sm text-red-500">
|
||||
{errors.reason?.message}
|
||||
</span>
|
||||
@ -107,5 +120,5 @@ export default function UserRejectDialog({ user }: { user: User }) {
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
);
|
||||
}
|
@ -12,7 +12,7 @@ import {
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import type { User } from "@prisma/client";
|
||||
import type { User } from "@/lib/types/user";
|
||||
import { Check, CheckCheck } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
@ -37,15 +37,20 @@ export function UserVerifyDialog({ user }: { user: User }) {
|
||||
<AlertDialogDescription>
|
||||
Are you sure you want to verify the following user?
|
||||
<span className="inline-block my-4">
|
||||
<li>Name: {user.name}</li>
|
||||
<li>
|
||||
Name: {user.first_name} {user.last_name}
|
||||
</li>
|
||||
<li>ID Card: {user.id_card}</li>
|
||||
<li>Address: {user.address}</li>
|
||||
<li>DOB: {new Date(user.dob ?? "").toLocaleDateString("en-US", {
|
||||
month: "short",
|
||||
day: "2-digit",
|
||||
year: "numeric",
|
||||
})}</li>
|
||||
<li>Phone Number: {user.phoneNumber}</li>
|
||||
<li>
|
||||
DOB:{" "}
|
||||
{new Date(user.dob ?? "").toLocaleDateString("en-US", {
|
||||
month: "short",
|
||||
day: "2-digit",
|
||||
year: "numeric",
|
||||
})}
|
||||
</li>
|
||||
<li>Phone Number: {user.mobile}</li>
|
||||
</span>
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
@ -55,7 +60,7 @@ export function UserVerifyDialog({ user }: { user: User }) {
|
||||
disabled={disabled}
|
||||
onClick={() => {
|
||||
setDisabled(true);
|
||||
toast.promise(VerifyUser(userId), {
|
||||
toast.promise(VerifyUser(String(userId)), {
|
||||
loading: "Verifying...",
|
||||
success: () => {
|
||||
setDisabled(false);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { Device } from "@prisma/client";
|
||||
import { atom, createStore } from "jotai";
|
||||
import type { Device } from "./backend-types";
|
||||
|
||||
// Create a single store instance
|
||||
export const store = createStore();
|
||||
|
@ -1,6 +1,6 @@
|
||||
"use server";
|
||||
import type { TNationalPerson } from "@/lib/types";
|
||||
import type { User } from "@prisma/client";
|
||||
import { User } from "./types/user";
|
||||
|
||||
export async function getNationalPerson({
|
||||
idCard,
|
||||
@ -18,26 +18,27 @@ export async function getNationalPerson({
|
||||
}
|
||||
|
||||
export async function VerifyUserDetails({ user }: { user: User }) {
|
||||
const phoneNumber = String(user.phoneNumber).slice(4);
|
||||
console.log({ phoneNumber });
|
||||
const nationalData = await getNationalPerson({ idCard: user.id_card ?? "" });
|
||||
const dob = new Date(nationalData.dob);
|
||||
const age = new Date().getFullYear() - dob.getFullYear();
|
||||
console.log(user)
|
||||
// const phoneNumber = String(user.phoneNumber).slice(4);
|
||||
// console.log({ phoneNumber });
|
||||
// const nationalData = await getNationalPerson({ idCard: user.id_card ?? "" });
|
||||
// const dob = new Date(nationalData.dob);
|
||||
// const age = new Date().getFullYear() - dob.getFullYear();
|
||||
|
||||
console.log("ID card", user.id_card === nationalData.nic);
|
||||
console.log("name", user.name === nationalData.name_en);
|
||||
console.log("house", user.address === nationalData.house_name_en);
|
||||
console.log("phone", phoneNumber === nationalData.primary_contact);
|
||||
console.log("db phone", phoneNumber);
|
||||
console.log("national phone", nationalData.primary_contact);
|
||||
// console.log("ID card", user.id_card === nationalData.nic);
|
||||
// console.log("name", user.name === nationalData.name_en);
|
||||
// console.log("house", user.address === nationalData.house_name_en);
|
||||
// console.log("phone", phoneNumber === nationalData.primary_contact);
|
||||
// console.log("db phone", phoneNumber);
|
||||
// console.log("national phone", nationalData.primary_contact);
|
||||
|
||||
if (
|
||||
user.id_card === nationalData.nic &&
|
||||
user.name === nationalData.name_en &&
|
||||
user.address === nationalData.house_name_en &&
|
||||
age >= 18
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
// if (
|
||||
// user.id_card === nationalData.nic &&
|
||||
// user.name === nationalData.name_en &&
|
||||
// user.address === nationalData.house_name_en &&
|
||||
// age >= 18
|
||||
// ) {
|
||||
// return true;
|
||||
// }
|
||||
return false;
|
||||
}
|
||||
|
@ -19,6 +19,10 @@ export interface User {
|
||||
user_permissions: Permission[];
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
id_card?: string;
|
||||
address?: string;
|
||||
verified?: boolean;
|
||||
dob?: string;
|
||||
mobile?: string;
|
||||
wallet_balance?: number;
|
||||
is_superuser: boolean;
|
||||
|
16143
package-lock.json
generated
16143
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
21
package.json
21
package.json
@ -6,14 +6,9 @@
|
||||
"dev": "next dev --turbopack",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
"studio": "npx prisma studio",
|
||||
"push": "npx prisma db push",
|
||||
"db-setup": "npx prisma migrate deploy && npx prisma generate && npx prisma db push"
|
||||
},
|
||||
"prisma": {
|
||||
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
|
||||
"lint": "next lint"
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"@faker-js/faker": "^9.3.0",
|
||||
"@hookform/resolvers": "^3.9.1",
|
||||
@ -39,14 +34,14 @@
|
||||
"lucide-react": "^0.460.0",
|
||||
"moment": "^2.30.1",
|
||||
"motion": "^11.15.0",
|
||||
"next": "15.1.2",
|
||||
"next": "15.3.0",
|
||||
"next-auth": "^4.24.11",
|
||||
"next-themes": "^0.4.3",
|
||||
"nextjs-toploader": "^3.7.15",
|
||||
"react": "19.0.0",
|
||||
"react": "19.1.0",
|
||||
"react-aria-components": "^1.5.0",
|
||||
"react-day-picker": "^9.6.3",
|
||||
"react-dom": "19.0.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-hook-form": "^7.53.2",
|
||||
"react-phone-number-input": "^3.4.9",
|
||||
"sonner": "^1.7.1",
|
||||
@ -57,14 +52,14 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.10.2",
|
||||
"@types/react": "^19.0.2",
|
||||
"@types/react-dom": "^19.0.2",
|
||||
"@types/react": "^19.1.0",
|
||||
"@types/react-dom": "^19.1.2",
|
||||
"eslint": "^9.17.0",
|
||||
"eslint-config-next": "15.1.2",
|
||||
"postcss": "^8.4.49",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.7.2"
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||
}
|
||||
|
@ -1,110 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "user" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT,
|
||||
"email" TEXT,
|
||||
"emailVerified" BOOLEAN NOT NULL DEFAULT false,
|
||||
"firstPaymentDone" BOOLEAN NOT NULL DEFAULT false,
|
||||
"verified" BOOLEAN NOT NULL DEFAULT false,
|
||||
"address" TEXT,
|
||||
"id_card" TEXT,
|
||||
"dob" TIMESTAMP(3),
|
||||
"image" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"phoneNumber" TEXT NOT NULL,
|
||||
"phoneNumberVerified" BOOLEAN NOT NULL DEFAULT false,
|
||||
"role" TEXT,
|
||||
"lang" TEXT,
|
||||
"atollId" TEXT,
|
||||
"islandId" TEXT,
|
||||
|
||||
CONSTRAINT "user_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "session" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"ipAddress" TEXT,
|
||||
"userAgent" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "session_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "account" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"accountId" TEXT NOT NULL,
|
||||
"providerId" TEXT NOT NULL,
|
||||
"accessToken" TEXT,
|
||||
"refreshToken" TEXT,
|
||||
"accessTokenExpiresAt" TIMESTAMP(3),
|
||||
"refreshTokenExpiresAt" TIMESTAMP(3),
|
||||
"scope" TEXT,
|
||||
"password" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"idToken" TEXT,
|
||||
|
||||
CONSTRAINT "account_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "verification" (
|
||||
"id" TEXT NOT NULL,
|
||||
"identifier" TEXT NOT NULL,
|
||||
"value" TEXT NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "verification_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Atoll" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Atoll_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Island" (
|
||||
"id" TEXT NOT NULL,
|
||||
"atollId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Island_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_email_key" ON "user"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_id_card_key" ON "user"("id_card");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_phoneNumber_key" ON "user"("phoneNumber");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "session_token_key" ON "session"("token");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "user" ADD CONSTRAINT "user_atollId_fkey" FOREIGN KEY ("atollId") REFERENCES "Atoll"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "user" ADD CONSTRAINT "user_islandId_fkey" FOREIGN KEY ("islandId") REFERENCES "Island"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Island" ADD CONSTRAINT "Island_atollId_fkey" FOREIGN KEY ("atollId") REFERENCES "Atoll"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,14 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "Device" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"mac" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"userId" TEXT,
|
||||
|
||||
CONSTRAINT "Device_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Device" ADD CONSTRAINT "Device_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
@ -1,29 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "user" ADD COLUMN "policyAccepted" BOOLEAN NOT NULL DEFAULT false,
|
||||
ADD COLUMN "termsAccepted" BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Bill" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"amount" INTEGER NOT NULL,
|
||||
"paid" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"deviceId" TEXT,
|
||||
|
||||
CONSTRAINT "Bill_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "BillFormula" (
|
||||
"id" TEXT NOT NULL,
|
||||
"formula" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "BillFormula_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Bill" ADD CONSTRAINT "Bill_deviceId_fkey" FOREIGN KEY ("deviceId") REFERENCES "Device"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
@ -1,10 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- Added the required column `baseAmount` to the `BillFormula` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `discountPercentage` to the `BillFormula` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "BillFormula" ADD COLUMN "baseAmount" DOUBLE PRECISION NOT NULL,
|
||||
ADD COLUMN "discountPercentage" DOUBLE PRECISION NOT NULL;
|
@ -1,2 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Device" ADD COLUMN "isActive" BOOLEAN NOT NULL DEFAULT false;
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the `Bill` table. If the table is not empty, all the data it contains will be lost.
|
||||
|
||||
*/
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Bill" DROP CONSTRAINT "Bill_deviceId_fkey";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Device" ADD COLUMN "billId" TEXT;
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE "Bill";
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Payment" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"amount" INTEGER NOT NULL,
|
||||
"paid" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "Payment_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Device" ADD CONSTRAINT "Device_billId_fkey" FOREIGN KEY ("billId") REFERENCES "Payment"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Payment" ADD CONSTRAINT "Payment_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,23 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `billId` on the `Device` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `name` on the `Payment` table. All the data in the column will be lost.
|
||||
- Added the required column `numberOfMonths` to the `Payment` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Device" DROP CONSTRAINT "Device_billId_fkey";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Device" DROP COLUMN "billId",
|
||||
ADD COLUMN "expiryDate" TIMESTAMP(3),
|
||||
ADD COLUMN "paymentId" TEXT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Payment" DROP COLUMN "name",
|
||||
ADD COLUMN "numberOfMonths" INTEGER NOT NULL,
|
||||
ALTER COLUMN "amount" SET DATA TYPE DOUBLE PRECISION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Device" ADD CONSTRAINT "Device_paymentId_fkey" FOREIGN KEY ("paymentId") REFERENCES "Payment"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
@ -1,2 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Payment" ADD COLUMN "paidAt" TIMESTAMP(3);
|
@ -1,2 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Payment" ADD COLUMN "expiresAt" TIMESTAMP(3);
|
@ -1,2 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "user" ADD COLUMN "accNo" TEXT;
|
@ -1,11 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `firstPaymentDone` on the `user` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Device" ADD COLUMN "registered" BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "user" DROP COLUMN "firstPaymentDone";
|
@ -1,2 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Device" ADD COLUMN "blocked" BOOLEAN NOT NULL DEFAULT false;
|
@ -1,2 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "user" ADD COLUMN "walletBalance" DOUBLE PRECISION NOT NULL DEFAULT 0;
|
@ -1,2 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Device" ADD COLUMN "reasonForBlocking" TEXT;
|
@ -1,11 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "Topup" (
|
||||
"id" TEXT NOT NULL,
|
||||
"amount" DOUBLE PRECISION NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"paid" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Topup_pkey" PRIMARY KEY ("id")
|
||||
);
|
@ -1,5 +0,0 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Blocker" AS ENUM ('ADMIN', 'PARENT');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Device" ADD COLUMN "blockedBy" "Blocker" NOT NULL DEFAULT 'PARENT';
|
@ -1,2 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "user" ADD COLUMN "ninja_user_id" TEXT;
|
@ -1,5 +0,0 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "PaymentType" AS ENUM ('WALLET', 'TRANSFER');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Payment" ADD COLUMN "method" "PaymentType" NOT NULL DEFAULT 'TRANSFER';
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `paymentId` on the `Device` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Device" DROP CONSTRAINT "Device_paymentId_fkey";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Device" DROP COLUMN "paymentId";
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "_DeviceToPayment" (
|
||||
"A" TEXT NOT NULL,
|
||||
"B" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "_DeviceToPayment_AB_pkey" PRIMARY KEY ("A","B")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "_DeviceToPayment_B_index" ON "_DeviceToPayment"("B");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "_DeviceToPayment" ADD CONSTRAINT "_DeviceToPayment_A_fkey" FOREIGN KEY ("A") REFERENCES "Device"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "_DeviceToPayment" ADD CONSTRAINT "_DeviceToPayment_B_fkey" FOREIGN KEY ("B") REFERENCES "Payment"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
@ -1,3 +0,0 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "postgresql"
|
@ -1,172 +0,0 @@
|
||||
// This is your Prisma schema file,
|
||||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||
|
||||
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
|
||||
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
binaryTargets = ["native", "debian-openssl-3.0.x"]
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
name String?
|
||||
email String? @unique
|
||||
emailVerified Boolean @default(false)
|
||||
|
||||
verified Boolean @default(false)
|
||||
accNo String?
|
||||
// island String?
|
||||
address String?
|
||||
id_card String? @unique
|
||||
dob DateTime?
|
||||
atoll Atoll? @relation(fields: [atollId], references: [id])
|
||||
island Island? @relation(fields: [islandId], references: [id])
|
||||
|
||||
image String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
phoneNumber String @unique
|
||||
phoneNumberVerified Boolean @default(false)
|
||||
termsAccepted Boolean @default(false)
|
||||
policyAccepted Boolean @default(false)
|
||||
walletBalance Float @default(0)
|
||||
ninja_user_id String?
|
||||
devices Device[]
|
||||
|
||||
role String?
|
||||
lang String?
|
||||
atollId String?
|
||||
islandId String?
|
||||
Bill Payment[]
|
||||
|
||||
@@map("user")
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
token String @unique
|
||||
expiresAt DateTime
|
||||
ipAddress String?
|
||||
userAgent String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("session")
|
||||
}
|
||||
|
||||
model Account {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
accountId String
|
||||
providerId String
|
||||
accessToken String?
|
||||
refreshToken String?
|
||||
accessTokenExpiresAt DateTime?
|
||||
refreshTokenExpiresAt DateTime?
|
||||
scope String?
|
||||
password String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
idToken String?
|
||||
|
||||
@@map("account")
|
||||
}
|
||||
|
||||
model Verification {
|
||||
id String @id @default(cuid())
|
||||
identifier String
|
||||
value String
|
||||
expiresAt DateTime
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("verification")
|
||||
}
|
||||
|
||||
model Atoll {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
islands Island[]
|
||||
User User[]
|
||||
}
|
||||
|
||||
model Island {
|
||||
id String @id @default(cuid())
|
||||
atollId String
|
||||
atoll Atoll @relation(fields: [atollId], references: [id])
|
||||
name String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
User User[]
|
||||
}
|
||||
|
||||
enum Blocker {
|
||||
ADMIN
|
||||
PARENT
|
||||
}
|
||||
|
||||
enum PaymentType {
|
||||
WALLET
|
||||
TRANSFER
|
||||
}
|
||||
|
||||
model Device {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
mac String
|
||||
reasonForBlocking String?
|
||||
isActive Boolean @default(false)
|
||||
registered Boolean @default(false)
|
||||
blocked Boolean @default(false)
|
||||
blockedBy Blocker @default(PARENT)
|
||||
expiryDate DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
User User? @relation(fields: [userId], references: [id])
|
||||
userId String?
|
||||
payments Payment[]
|
||||
}
|
||||
|
||||
model Payment {
|
||||
id String @id @default(cuid())
|
||||
numberOfMonths Int
|
||||
amount Float
|
||||
paid Boolean @default(false)
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
paidAt DateTime?
|
||||
method PaymentType @default(TRANSFER)
|
||||
expiresAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
devices Device[]
|
||||
userId String
|
||||
}
|
||||
|
||||
model BillFormula {
|
||||
id String @id @default(cuid())
|
||||
formula String
|
||||
baseAmount Float
|
||||
discountPercentage Float
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model Topup {
|
||||
id String @id @default(cuid())
|
||||
amount Float
|
||||
userId String
|
||||
paid Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
const DEFAULT_ISLANDS = ["Dharanboodhoo", "Feeali", "Nilandhoo", "Magoodhoo"];
|
||||
|
||||
async function main() {
|
||||
await prisma.user.upsert({
|
||||
where: {
|
||||
phoneNumber: process.env.ADMIN_PHONENUMBER,
|
||||
},
|
||||
update: {},
|
||||
create: {
|
||||
name: process.env.ADMIN_FULLNAME,
|
||||
email: process.env.ADMIN_EMAIL,
|
||||
emailVerified: true,
|
||||
verified: true,
|
||||
address: process.env.ADMIN_ADDRESS,
|
||||
id_card: process.env.ADMIN_IDCARD,
|
||||
dob: new Date("1999-05-06"),
|
||||
phoneNumber: process.env.ADMIN_PHONENUMBER ?? "",
|
||||
phoneNumberVerified: true,
|
||||
role: "ADMIN",
|
||||
},
|
||||
});
|
||||
let FAAFU_ATOLL_ID = "";
|
||||
const atollExists = await prisma.atoll.findFirst({
|
||||
where: {
|
||||
name: "F",
|
||||
},
|
||||
});
|
||||
if (!atollExists) {
|
||||
const NEW_ATOLL = await prisma.atoll.create({
|
||||
data: {
|
||||
name: "F",
|
||||
},
|
||||
});
|
||||
FAAFU_ATOLL_ID = NEW_ATOLL.id;
|
||||
|
||||
const islands = DEFAULT_ISLANDS.map((name) => ({
|
||||
name,
|
||||
atollId: FAAFU_ATOLL_ID,
|
||||
}));
|
||||
await prisma.island.createMany({
|
||||
data: islands,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => prisma.$disconnect())
|
||||
.catch(async (e) => {
|
||||
console.error(e);
|
||||
await prisma.$disconnect();
|
||||
process.exit(1);
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user