From 720b64c2220e7eb8afddbb44d784ae985af94a69 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Tue, 1 Oct 2024 23:31:40 +0530 Subject: [PATCH 01/35] Refactor user API route to include pagination and search functionality --- src/app/api/users/payment/route.ts | 50 +++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/src/app/api/users/payment/route.ts b/src/app/api/users/payment/route.ts index 64fabec..5f35aed 100644 --- a/src/app/api/users/payment/route.ts +++ b/src/app/api/users/payment/route.ts @@ -4,9 +4,51 @@ import { NextRequest, NextResponse } from "next/server"; export async function GET(request: NextRequest) { const { searchParams } = new URL(request.url); + try { + const page = Math.max(1, parseInt(searchParams.get("page") || "1", 10)); + const search = searchParams.get("search") || ""; + const limit = 10; - const page = Math.max(1, parseInt(searchParams.get("page") || "1", 10)); - const search = searchParams.get("search") || ""; - const limit = 10; - const paymentDetails = await prisma.payment.findMany({}); + const [users, totalCount] = await Promise.all([ + prisma.payment.findMany({ + skip: (page - 1) * limit, + take: limit, + where: { + razorpayPaymentId: { + contains: search, + }, + }, + include: { + user: { + select: { + name: true, + email: true, + }, + }, + }, + }), + prisma.payment.count({ + where: { + razorpayPaymentId: { + contains: search, + }, + }, + }), + ]); + + const totalPages = Math.ceil(totalCount / limit); + + return NextResponse.json({ + users, + pagination: { + currentPage: page, + totalCount, + totalPages, + limit, + }, + }); + } catch (error) { + console.error("Error fetching payment details:", error); + return NextResponse.json({ error: "Failed to fetch data" }, { status: 500 }); + } } From 9be2bb79cbca59aa095567815329008fe446e145 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Tue, 1 Oct 2024 23:31:48 +0530 Subject: [PATCH 02/35] Refactor searchable infinite scroll table component to include pagination and search functionality --- .../searchable-infinite-scroll-table.tsx | 276 ++++++++++-------- 1 file changed, 153 insertions(+), 123 deletions(-) diff --git a/src/components/searchable-infinite-scroll-table.tsx b/src/components/searchable-infinite-scroll-table.tsx index 74509d9..05e190a 100644 --- a/src/components/searchable-infinite-scroll-table.tsx +++ b/src/components/searchable-infinite-scroll-table.tsx @@ -1,139 +1,169 @@ "use client"; -import { useEffect, useRef, useState } from "react"; -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "@/components/ui/table"; +import { useEffect, useRef, useState, useCallback } from "react"; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Input } from "@/components/ui/input"; import { Loader2, Search } from "lucide-react"; +import axios from "axios"; +import debounce from "lodash.debounce"; interface TableData { - name: string; - email: string; - usn: string; - paymentId: string; - contactNumber: string; - amount: number; -} - -function generateMockData(count: number): TableData[] { - return Array.from({ length: count }, (_, i) => ({ - name: `User ${i + 1}`, - email: `user${i + 1}@example.com`, - usn: `USN${(1000 + i).toString().padStart(4, "0")}`, - paymentId: `PAY${(10000 + i).toString().padStart(5, "0")}`, - contactNumber: `+1 ${Math.floor(1000000000 + Math.random() * 9000000000)}`, - amount: Math.floor(10 + Math.random() * 990), - })); + user: { + name: string; + email: string; + }; + usn: string; + razorpayPaymentId: string; + contactNumber: string; + amount: number; } export function SearchableInfiniteScrollTable() { - const [data, setData] = useState([]); - const [filteredData, setFilteredData] = useState([]); - const [isLoading, setIsLoading] = useState(false); - const [page, setPage] = useState(1); - const [searchTerm, setSearchTerm] = useState(""); - const loaderRef = useRef(null); - - const loadMoreData = () => { - setIsLoading(true); - setTimeout(() => { - const newData = generateMockData(20); - setData((prevData) => [...prevData, ...newData]); - setPage((prevPage) => prevPage + 1); - setIsLoading(false); - }, 1000); // Simulating API delay - }; - - useEffect(() => { - loadMoreData(); - }, []); - - useEffect(() => { - const filtered = data.filter((item) => - Object.values(item).some((value) => - value.toString().toLowerCase().includes(searchTerm.toLowerCase()), - ), - ); - setFilteredData(filtered); - }, [data, searchTerm]); - - useEffect(() => { - const observer = new IntersectionObserver( - (entries) => { - if (entries[0].isIntersecting && !isLoading && searchTerm === "") { - loadMoreData(); + const [data, setData] = useState([]); + const [filteredData, setFilteredData] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [page, setPage] = useState(1); + const [searchTerm, setSearchTerm] = useState(""); + const [hasMoreData, setHasMoreData] = useState(true); + const loaderRef = useRef(null); + const observerRef = useRef(null); + + const getPaymentDetails = async (page: number, query: string) => { + if (isLoading || !hasMoreData) return; + + setIsLoading(true); + try { + const response = await axios.get( + `/api/users/payment?page=${page}&search=${encodeURIComponent(query)}` + ); + const users = response.data.users; + + if (users.length === 0) { + setHasMoreData(false); // No more data to load + } + + setData((prevData) => { + const newData = [...prevData, ...users]; + // Remove duplicates + const uniqueData = Array.from( + new Map(newData.map((item) => [item.razorpayPaymentId, item])).values() + ); + return uniqueData; + }); + setPage((prevPage) => prevPage + 1); + } catch (error) { + console.error("Error fetching payment details:", error); + } finally { + setIsLoading(false); + } + }; + + const loadMoreData = () => { + if (searchTerm === "") { + getPaymentDetails(page, ""); + } + }; + + const fetchSearchResults = useCallback(async (query: string) => { + setPage(1); // Reset page number + setHasMoreData(true); // Reset hasMoreData + try { + const response = await axios.get(`/api/users/payment?page=1&search=${encodeURIComponent(query)}`); + const users = response.data.users; + setData(users); // Set new data from search + setFilteredData(users); // Set filtered data to the same as new data + } catch (error) { + console.error("Error fetching payment details:", error); } - }, - { threshold: 1.0 }, + }, []); + + // eslint-disable-next-line react-hooks/exhaustive-deps + const debouncedFetch = useCallback( + debounce((query: string) => { + fetchSearchResults(query); + }, 500), + [] ); - if (loaderRef.current) { - observer.observe(loaderRef.current); - } + const handleSearch = (event: React.ChangeEvent) => { + const value = event.target.value; + setSearchTerm(value); + debouncedFetch(value); // Use debounced fetch function + }; - return () => { - if (loaderRef.current) { + useEffect(() => { + loadMoreData(); // Initial load // eslint-disable-next-line react-hooks/exhaustive-deps - observer.unobserve(loaderRef.current); - } - observer.disconnect(); - }; - }, [isLoading, searchTerm]); - - const handleSearch = (event: React.ChangeEvent) => { - setSearchTerm(event.target.value); - }; - - return ( -
-
- - -
- - - - Name - Email - USN - Payment ID - Contact Number - Amount - - - - {filteredData.map((item, index) => ( - - {item.name} - {item.email} - {item.usn} - {item.paymentId} - {item.contactNumber} - ${item.amount.toFixed(2)} - - ))} - -
- {searchTerm === "" && ( -
- {isLoading && } + }, []); + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + if (entries[0].isIntersecting && !isLoading) { + loadMoreData(); + } + }, + { threshold: 1.0 } + ); + + if (loaderRef.current) { + observer.observe(loaderRef.current); + } + + return () => { + if (loaderRef.current) { + // eslint-disable-next-line react-hooks/exhaustive-deps + observer.unobserve(loaderRef.current); + } + observer.disconnect(); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isLoading]); + + return ( +
+
+ + +
+ + + + Name + Email + USN + Payment ID + Contact Number + Amount + + + + {(searchTerm ? filteredData : data).map((item, index) => ( + + {item.user.name} + {item.user.email} + {item.usn} + {item.razorpayPaymentId} + {item.contactNumber} + ${item.amount.toFixed(2)} + + ))} + +
+ {searchTerm === "" && hasMoreData && ( +
+ {isLoading && } +
+ )}
- )} -
- ); + ); } From cae0c99041fc63b53ef98762f5ead8d97acaf8d7 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Tue, 1 Oct 2024 23:31:53 +0530 Subject: [PATCH 03/35] Refactor searchable infinite scroll table component to include pagination and search functionality --- src/components/Admin/user-list.tsx | 290 ++++++++++++++--------------- 1 file changed, 138 insertions(+), 152 deletions(-) diff --git a/src/components/Admin/user-list.tsx b/src/components/Admin/user-list.tsx index 66ba46b..75232bd 100644 --- a/src/components/Admin/user-list.tsx +++ b/src/components/Admin/user-list.tsx @@ -1,15 +1,9 @@ /* eslint-disable react-hooks/exhaustive-deps */ "use client"; -import { useState, useEffect, useRef, useCallback } from "react"; +import React, { useState, useEffect, useRef, useCallback } from "react"; import axios from "axios"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "../ui/card"; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card"; import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar"; import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; import { Button } from "../ui/button"; @@ -19,161 +13,153 @@ import debounce from "lodash.debounce"; import ChangeRole from "./change-role"; export interface User { - id: string; - name: string | null; - email: string | null; - role: string; - image: string | null; + id: string; + name: string | null; + email: string | null; + role: string; + image: string | null; } interface UsersListProps { - initialUsers: User[]; - initialPage: number; + initialUsers: User[]; + initialPage: number; } export const dynamic = "force-dynamic"; const UsersList: React.FC = ({ initialUsers, initialPage }) => { - const [userList, setUserList] = useState(initialUsers); - const [currentPage, setCurrentPage] = useState(initialPage); - const [loading, setLoading] = useState(false); - const [hasMore, setHasMore] = useState(true); - const [searchQuery, setSearchQuery] = useState(""); // Search query state - const loader = useRef(null); + const [userList, setUserList] = useState(initialUsers); + const [currentPage, setCurrentPage] = useState(initialPage); + const [loading, setLoading] = useState(false); + const [hasMore, setHasMore] = useState(true); + const [searchQuery, setSearchQuery] = useState(""); // Search query state + const loader = useRef(null); - const fetchUsers = async (page: number, query: string) => { - if (loading) return; - setLoading(true); - try { - const response = await axios.get( - `/api/users?page=${page}&search=${encodeURIComponent(query)}`, - ); - if (response.data.users.length > 0) { - setUserList((prevUsers) => [...prevUsers, ...response.data.users]); - setCurrentPage(page); - } else { - setHasMore(false); - } - } catch (error) { - console.error("Error fetching users:", error); - } - setLoading(false); - }; - const loadMoreUsers = useCallback(() => { - if (hasMore) { - fetchUsers(currentPage + 1, searchQuery); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [currentPage, hasMore, searchQuery]); + const fetchUsers = async (page: number, query: string) => { + if (loading) return; + setLoading(true); + try { + const response = await axios.get(`/api/users?page=${page}&search=${encodeURIComponent(query)}`); + if (response.data.users.length > 0) { + setUserList((prevUsers) => [...prevUsers, ...response.data.users]); + setCurrentPage(page); + } else { + setHasMore(false); + } + } catch (error) { + console.error("Error fetching users:", error); + } + setLoading(false); + }; + const loadMoreUsers = useCallback(() => { + if (hasMore) { + fetchUsers(currentPage + 1, searchQuery); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPage, hasMore, searchQuery]); - const debouncedFetchUsers = useCallback( - debounce(async (query: string) => { - setCurrentPage(1); // Reset page number - setHasMore(true); // Reset hasMore - try { - const response = await axios.get( - `/api/users?page=1&search=${encodeURIComponent(query)}`, - ); - setUserList(response.data.users); - } catch (error) { - console.error("Error fetching users:", error); - } - }, 500), - [], - ); - const handleSearchChange = (e: React.ChangeEvent) => { - const query = e.target.value; - setSearchQuery(query); - debouncedFetchUsers(query); // Use debounced fetch function - }; + const debouncedFetchUsers = useCallback( + debounce(async (query: string) => { + setCurrentPage(1); // Reset page number + setHasMore(true); // Reset hasMore + try { + const response = await axios.get(`/api/users?page=1&search=${encodeURIComponent(query)}`); + setUserList(response.data.users); + } catch (error) { + console.error("Error fetching users:", error); + } + }, 500), + [] + ); + const handleSearchChange = (e: React.ChangeEvent) => { + const query = e.target.value; + setSearchQuery(query); + debouncedFetchUsers(query); // Use debounced fetch function + }; - // Observe scroll and load more users when scrolled to the bottom - useEffect(() => { - if (loader.current) { - const observer = new IntersectionObserver( - (entries) => { - if (entries[0].isIntersecting && hasMore) { - loadMoreUsers(); - } - }, - { threshold: 1.0 }, - ); - observer.observe(loader.current); - return () => observer.disconnect(); - } - }, [loader.current, hasMore, loadMoreUsers]); + // Observe scroll and load more users when scrolled to the bottom + useEffect(() => { + if (loader.current) { + const observer = new IntersectionObserver( + (entries) => { + if (entries[0].isIntersecting && hasMore) { + loadMoreUsers(); + } + }, + { threshold: 1.0 } + ); + observer.observe(loader.current); + return () => observer.disconnect(); + } + }, [loader.current, hasMore, loadMoreUsers]); - return ( - <> -
-
- -
-
- - -
+ return ( + <> +
+
+ +
+
+ + +
+
+ + Users + Manage user roles and permissions. + + +
+ {userList.map((user) => ( +
+
+ + + + {user.name ? user.name[0] : "N/A"} + + +
+

+ {user.name || "Unknown"} +

+

+ {user.email || "No email"} +

+
+
+ + + + + + + + +
+ ))} +
+ {hasMore && ( +
+ {loading ? "Loading..." : "Load more"} +
+ )} +
+
+
- - Users - - Manage user roles and permissions. - - - -
- {userList.map((user) => ( -
-
- - - - {user.name ? user.name[0] : "N/A"} - - -
-

- {user.name || "Unknown"} -

-

- {user.email || "No email"} -

-
-
- - - - - - - - -
- ))} -
- {hasMore && ( -
- {loading ? "Loading..." : "Load more"} -
- )} -
- -
-
- - ); + + ); }; export default UsersList; From 4c4d4ed2ad08b6923588862e7b7914d8e9927735 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 10:37:11 +0530 Subject: [PATCH 04/35] Refactor package.json to add email dev script and update dependencies --- package-lock.json | 352 +++++++--------------------------------------- package.json | 5 +- 2 files changed, 56 insertions(+), 301 deletions(-) diff --git a/package-lock.json b/package-lock.json index c673e68..689a8c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,8 +26,10 @@ "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tabs": "^1.1.0", "@react-email/components": "^0.0.25", + "@react-email/tailwind": "0.1.0", "@react-three/drei": "^9.114.0", "@tanstack/react-query": "^5.56.2", + "@types/canvas-confetti": "^1.6.4", "@types/ioredis": "^4.28.10", "@types/lodash.debounce": "^4.0.9", "@uploadthing/react": "^7.0.2", @@ -46,11 +48,12 @@ "next-auth": "^4.24.7", "nodemailer": "^6.9.15", "otp-generator": "^4.0.1", + "razorpay": "^2.9.4", "react": "^18.3.1", "react-dom": "^18", "react-email": "^3.0.1", - "react-icons": "^5.3.0", "react-hook-form": "^7.53.0", + "react-icons": "^5.3.0", "resend": "^4.0.0", "sonner": "^1.5.0", "tailwind-merge": "^2.5.2", @@ -3384,7 +3387,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/@react-email/tailwind/-/tailwind-0.1.0.tgz", "integrity": "sha512-qysVUEY+M3SKUvu35XDpzn7yokhqFOT3tPU6Mj/pgc62TL5tQFj6msEbBtwoKs2qO3WZvai0DIHdLhaOxBQSow==", - "license": "MIT", "engines": { "node": ">=18.0.0" }, @@ -10107,15 +10109,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pirates": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", @@ -10511,6 +10504,14 @@ } ] }, + "node_modules/razorpay": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/razorpay/-/razorpay-2.9.4.tgz", + "integrity": "sha512-CvOitdgM5HNr+zl174fHpZoJKVFYEfPoGx798kX+kg3haGDD3xinzxTzRUIOzLnL1/F4e7mUoIaGNn0h1E929Q==", + "dependencies": { + "axios": "^1.6.8" + } + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -10930,19 +10931,10 @@ "semver": "bin/semver.js" } }, - - "node_modules/react-icons": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", - "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", - "peerDependencies": { - "react": "*" - }, "node_modules/react-hook-form": { "version": "7.53.0", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.53.0.tgz", "integrity": "sha512-M1n3HhqCww6S2hxLxciEXy2oISPnAzxY7gvwVPrtlczTM/1dDadXgUxDpHMrMTblDOcm/AXtXxHwZ3jpg1mqKQ==", - "license": "MIT", "engines": { "node": ">=18.0.0" }, @@ -10954,17 +10946,23 @@ "react": "^16.8.0 || ^17 || ^18 || ^19" } }, + "node_modules/react-icons": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", + "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-promise-suspense": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/react-promise-suspense/-/react-promise-suspense-0.3.4.tgz", "integrity": "sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ==", - "license": "MIT", "dependencies": { "fast-deep-equal": "^2.0.1" } @@ -10972,14 +10970,12 @@ "node_modules/react-promise-suspense/node_modules/fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", - "license": "MIT" + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" }, "node_modules/react-reconciler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz", "integrity": "sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==", - "license": "MIT", "peer": true, "dependencies": { "loose-envify": "^1.1.0", @@ -10996,7 +10992,6 @@ "version": "2.5.7", "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz", "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==", - "license": "MIT", "dependencies": { "react-remove-scroll-bar": "^2.3.4", "react-style-singleton": "^2.2.1", @@ -11021,7 +11016,6 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", - "license": "MIT", "dependencies": { "react-style-singleton": "^2.2.1", "tslib": "^2.0.0" @@ -11043,7 +11037,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", - "license": "MIT", "dependencies": { "get-nonce": "^1.0.0", "invariant": "^2.2.4", @@ -11062,20 +11055,10 @@ } } }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -11089,7 +11072,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -11101,7 +11083,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", - "license": "MIT", "engines": { "node": ">=4" } @@ -11110,7 +11091,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", - "license": "MIT", "dependencies": { "redis-errors": "^1.0.0" }, @@ -11123,7 +11103,6 @@ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -11143,15 +11122,13 @@ "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "license": "MIT" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "define-properties": "^1.2.1", @@ -11169,16 +11146,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11187,7 +11154,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resend/-/resend-4.0.0.tgz", "integrity": "sha512-rDX0rspl/XcmC2JV2V5obQvRX2arzxXUvNFUDMOv5ObBLR68+7kigCOysb7+dlkb0JE3erhQG0nHrbBt/ZCWIg==", - "license": "MIT", "dependencies": { "@react-email/render": "0.0.17" }, @@ -11199,7 +11165,6 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -11216,7 +11181,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -11228,7 +11192,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "license": "MIT", "engines": { "node": ">=8" } @@ -11238,7 +11201,6 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } @@ -11248,7 +11210,6 @@ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } @@ -11257,7 +11218,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "license": "MIT", "engines": { "node": ">=10" } @@ -11266,7 +11226,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -11278,14 +11237,12 @@ "node_modules/restore-cursor/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -11297,7 +11254,6 @@ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -11314,7 +11270,6 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -11348,7 +11303,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -11358,7 +11312,6 @@ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -11389,15 +11342,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/safe-regex-test": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -11414,7 +11365,6 @@ "version": "0.21.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", - "license": "MIT", "peer": true, "dependencies": { "loose-envify": "^1.1.0" @@ -11424,7 +11374,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz", "integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==", - "license": "MIT", "dependencies": { "parseley": "^0.12.0" }, @@ -11436,7 +11385,6 @@ "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -11449,7 +11397,6 @@ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, - "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -11467,7 +11414,6 @@ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, - "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -11482,7 +11428,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -11494,7 +11439,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", "engines": { "node": ">=8" } @@ -11504,7 +11448,6 @@ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -11522,7 +11465,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", "engines": { "node": ">=14" }, @@ -11533,14 +11475,12 @@ "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "license": "MIT" + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", "engines": { "node": ">=8" } @@ -11549,7 +11489,6 @@ "version": "4.7.5", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", - "license": "MIT", "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", @@ -11567,7 +11506,6 @@ "version": "2.5.5", "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", - "license": "MIT", "dependencies": { "debug": "~4.3.4", "ws": "~8.17.1" @@ -11577,7 +11515,6 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -11598,7 +11535,6 @@ "version": "4.2.4", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", - "license": "MIT", "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" @@ -11611,7 +11547,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/sonner/-/sonner-1.5.0.tgz", "integrity": "sha512-FBjhG/gnnbN6FY0jaNnqZOMmB73R+5IiyYAw8yBj7L54ER7HB3fOSE5OFiQiE2iXWxeXKvg6fIP4LtVppHEdJA==", - "license": "MIT", "peerDependencies": { "react": "^18.0.0", "react-dom": "^18.0.0" @@ -11621,7 +11556,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -11630,7 +11564,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -11639,7 +11572,6 @@ "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -11648,20 +11580,17 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause" + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/sqids": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/sqids/-/sqids-0.3.0.tgz", - "integrity": "sha512-lOQK1ucVg+W6n3FhRwwSeUijxe93b51Bfz5PMRMihVf1iVkl82ePQG7V5vwrhzB11v0NtsR25PSZRGiSomJaJw==", - "license": "MIT" + "integrity": "sha512-lOQK1ucVg+W6n3FhRwwSeUijxe93b51Bfz5PMRMihVf1iVkl82ePQG7V5vwrhzB11v0NtsR25PSZRGiSomJaJw==" }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -11673,7 +11602,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "license": "MIT", "engines": { "node": ">=8" } @@ -11681,14 +11609,12 @@ "node_modules/standard-as-callback": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", - "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", - "license": "MIT" + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" }, "node_modules/stats-gl": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-2.2.8.tgz", "integrity": "sha512-94G5nZvduDmzxBS7K0lYnynYwreZpkknD8g5dZmU6mpwIhy3caCrjAm11Qm1cbyx7mqix7Fp00RkbsonzKWnoQ==", - "license": "MIT", "dependencies": { "@types/three": "^0.163.0" } @@ -11697,7 +11623,6 @@ "version": "0.163.0", "resolved": "https://registry.npmjs.org/@types/three/-/three-0.163.0.tgz", "integrity": "sha512-uIdDhsXRpQiBUkflBS/i1l3JX14fW6Ot9csed60nfbZNXHDTRsnV2xnTVwXcgbvTiboAR4IW+t+lTL5f1rqIqA==", - "license": "MIT", "dependencies": { "@tweenjs/tween.js": "~23.1.1", "@types/stats.js": "*", @@ -11709,15 +11634,13 @@ "node_modules/stats.js": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", - "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==", - "license": "MIT" + "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==" }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", "dev": true, - "license": "MIT", "dependencies": { "internal-slot": "^1.0.4" }, @@ -11737,7 +11660,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } @@ -11746,7 +11668,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -11759,7 +11680,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -11777,7 +11697,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -11790,14 +11709,12 @@ "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", "engines": { "node": ">=12" }, @@ -11809,7 +11726,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -11825,7 +11741,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", "dev": true, - "license": "MIT", "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" @@ -11836,7 +11751,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -11863,7 +11777,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", "dev": true, - "license": "MIT", "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" @@ -11874,7 +11787,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -11893,7 +11805,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -11908,7 +11819,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -11925,7 +11835,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -11938,7 +11847,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -11951,7 +11859,6 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } @@ -11960,7 +11867,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "license": "MIT", "engines": { "node": ">=6" } @@ -11969,7 +11875,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", "engines": { "node": ">=8" }, @@ -11981,7 +11886,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", - "license": "MIT", "dependencies": { "client-only": "0.0.1" }, @@ -12004,7 +11908,6 @@ "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", @@ -12026,7 +11929,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -12038,7 +11940,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -12050,7 +11951,6 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz", "integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==", - "license": "MIT", "peerDependencies": { "react": ">=17.0" } @@ -12059,7 +11959,6 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.2.tgz", "integrity": "sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==", - "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/dcastil" @@ -12069,7 +11968,6 @@ "version": "3.4.13", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz", "integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==", - "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -12106,7 +12004,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", - "license": "MIT", "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } @@ -12116,7 +12013,6 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -12125,7 +12021,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -12140,7 +12035,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -12160,42 +12054,18 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } + "dev": true }, "node_modules/three": { "version": "0.169.0", "resolved": "https://registry.npmjs.org/three/-/three-0.169.0.tgz", - "integrity": "sha512-Ed906MA3dR4TS5riErd4QBsRGPcx+HBDX2O5yYE5GqJeFQTPU+M56Va/f/Oph9X7uZo3W3o4l2ZhBZ6f6qUv0w==", - "license": "MIT" + "integrity": "sha512-Ed906MA3dR4TS5riErd4QBsRGPcx+HBDX2O5yYE5GqJeFQTPU+M56Va/f/Oph9X7uZo3W3o4l2ZhBZ6f6qUv0w==" }, "node_modules/three-mesh-bvh": { "version": "0.7.8", "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.7.8.tgz", "integrity": "sha512-BGEZTOIC14U0XIRw3tO4jY7IjP7n7v24nv9JXS1CyeVRWOCkcOMhRnmENUjuV39gktAw4Ofhr0OvIAiTspQrrw==", "deprecated": "Deprecated due to three.js version incompatibility. Please use v0.8.0, instead.", - "license": "MIT", "peerDependencies": { "three": ">= 0.151.0" } @@ -12204,7 +12074,6 @@ "version": "2.33.0", "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.33.0.tgz", "integrity": "sha512-V/uycBuqQOP/3Z+FBtpMdj2Ds5PyfJ3VDfMzktEmG4niOIzv7q1y5uMSbMcng0+057m1l0N147FQxsodQo9zBg==", - "license": "MIT", "dependencies": { "@types/draco3d": "^1.4.0", "@types/offscreencanvas": "^2019.6.4", @@ -12220,45 +12089,12 @@ "node_modules/three-stdlib/node_modules/fflate": { "version": "0.6.10", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", - "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==", - "license": "MIT" - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "license": "BSD-3-Clause" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "license": "BSD-3-Clause" + "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==" }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "license": "MIT", "engines": { "node": ">=4" } @@ -12267,7 +12103,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -12279,7 +12114,6 @@ "version": "0.49.1", "resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.49.1.tgz", "integrity": "sha512-lXGWxgjJP9kw4i4Wh+0k0Q/7cRfS6iOME4knKht/KozPu9GcFA9NnNpRvehIhrUawq9B0ZRw+0oiFHgRO+4Wig==", - "license": "MIT", "dependencies": { "bidi-js": "^1.0.2", "troika-three-utils": "^0.49.0", @@ -12294,7 +12128,6 @@ "version": "0.49.0", "resolved": "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.49.0.tgz", "integrity": "sha512-umitFL4cT+Fm/uONmaQEq4oZlyRHWwVClaS6ZrdcueRvwc2w+cpNQ47LlJKJswpqtMFWbEhOLy0TekmcPZOdYA==", - "license": "MIT", "peerDependencies": { "three": ">=0.125.0" } @@ -12302,15 +12135,13 @@ "node_modules/troika-worker-utils": { "version": "0.49.0", "resolved": "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.49.0.tgz", - "integrity": "sha512-1xZHoJrG0HFfCvT/iyN41DvI/nRykiBtHqFkGaGgJwq5iXfIZFBiPPEHFpPpgyKM3Oo5ITHXP5wM2TNQszYdVg==", - "license": "MIT" + "integrity": "sha512-1xZHoJrG0HFfCvT/iyN41DvI/nRykiBtHqFkGaGgJwq5iXfIZFBiPPEHFpPpgyKM3Oo5ITHXP5wM2TNQszYdVg==" }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=16" }, @@ -12321,15 +12152,13 @@ "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "license": "Apache-2.0" + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, - "license": "MIT", "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -12340,14 +12169,12 @@ "node_modules/tslib": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "license": "0BSD" + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" }, "node_modules/tunnel-rat": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/tunnel-rat/-/tunnel-rat-0.1.2.tgz", "integrity": "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==", - "license": "MIT", "dependencies": { "zustand": "^4.3.2" } @@ -12356,7 +12183,6 @@ "version": "4.5.5", "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.5.tgz", "integrity": "sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q==", - "license": "MIT", "dependencies": { "use-sync-external-store": "1.2.2" }, @@ -12385,7 +12211,6 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -12397,7 +12222,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "license": "MIT", "engines": { "node": ">=4" } @@ -12407,7 +12231,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -12420,7 +12243,6 @@ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -12435,7 +12257,6 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -12455,7 +12276,6 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, - "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -12476,7 +12296,6 @@ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -12493,11 +12312,10 @@ } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -12511,7 +12329,6 @@ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -12525,13 +12342,12 @@ "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "funding": [ { "type": "opencollective", @@ -12546,10 +12362,9 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -12562,7 +12377,6 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/uploadthing/-/uploadthing-7.0.2.tgz", "integrity": "sha512-B5/r0nmOfWjo+cGvZLyDQ8jypJYWoW/VsmoL+VqkiGMg5yIkKzMGJ5InrDOJS+3WQBbW8KdhVrRyA+mGSZEGUw==", - "license": "MIT", "dependencies": { "@effect/platform": "0.63.2", "@effect/schema": "0.72.2", @@ -12604,7 +12418,6 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -12613,7 +12426,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", - "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -12634,7 +12446,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", - "license": "MIT", "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" @@ -12656,7 +12467,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", - "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } @@ -12664,14 +12474,12 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utility-types": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", - "license": "MIT", "engines": { "node": ">= 4" } @@ -12684,7 +12492,6 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], - "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -12693,7 +12500,6 @@ "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", @@ -12703,20 +12509,10 @@ "node": ">=10.12.0" } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } @@ -12725,7 +12521,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "license": "MIT", "dependencies": { "defaults": "^1.0.3" } @@ -12734,7 +12529,6 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "license": "MIT", "engines": { "node": ">= 8" } @@ -12747,14 +12541,12 @@ "node_modules/webgl-sdf-generator": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz", - "integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==", - "license": "MIT" + "integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==" }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -12770,7 +12562,6 @@ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -12787,7 +12578,6 @@ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", "dev": true, - "license": "MIT", "dependencies": { "function.prototype.name": "^1.1.6", "has-tostringtag": "^1.0.2", @@ -12814,7 +12604,6 @@ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, - "license": "MIT", "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", @@ -12833,7 +12622,6 @@ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, - "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -12853,7 +12641,6 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -12862,7 +12649,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -12880,7 +12666,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -12896,14 +12681,12 @@ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -12917,7 +12700,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", "engines": { "node": ">=12" }, @@ -12929,7 +12711,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "license": "MIT", "engines": { "node": ">=12" }, @@ -12941,7 +12722,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -12955,14 +12735,12 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" @@ -12974,14 +12752,12 @@ "node_modules/write-file-atomic/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/ws": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -13002,7 +12778,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", "engines": { "node": ">=10" } @@ -13010,26 +12785,12 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -13047,7 +12808,6 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", "engines": { "node": ">=12" } @@ -13055,14 +12815,12 @@ "node_modules/yargs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/yargs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -13076,7 +12834,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "license": "MIT", "engines": { "node": ">=10" }, @@ -13088,7 +12845,6 @@ "version": "3.23.8", "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -13097,7 +12853,6 @@ "version": "3.7.2", "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", - "license": "MIT", "engines": { "node": ">=12.7.0" }, @@ -13112,4 +12867,3 @@ } } } -} diff --git a/package.json b/package.json index adf90f5..ffc2f92 100644 --- a/package.json +++ b/package.json @@ -8,9 +8,9 @@ "build": "next build", "start": "next start", "lint": "next lint", + "email": "email dev", "migrate-latest": "export $(grep -v '^#' .env | xargs) && LATEST_MIGRATION=$(find prisma/migrations/*/ -type d -name '[0-9]*_*' | sort -r | head -n 1) && turso db shell $TURSO_DB_NAME < ${LATEST_MIGRATION}migration.sql", "migrate-latest-w": "wsl sh -c \"export $(grep -v '^#' .env.local | xargs) && LATEST_MIGRATION=$(find prisma/migrations/*/ -type d -name '[0-9]*_*' | sort -r | head -n 1) && turso db shell $TURSO_DB_NAME < '${LATEST_MIGRATION}migration.sql'\"" - }, "dependencies": { "@hookform/resolvers": "^3.9.0", @@ -31,6 +31,7 @@ "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tabs": "^1.1.0", "@react-email/components": "^0.0.25", + "@react-email/tailwind": "0.1.0", "@react-three/drei": "^9.114.0", "@tanstack/react-query": "^5.56.2", "@types/canvas-confetti": "^1.6.4", @@ -56,8 +57,8 @@ "react": "^18.3.1", "react-dom": "^18", "react-email": "^3.0.1", - "react-icons": "^5.3.0", "react-hook-form": "^7.53.0", + "react-icons": "^5.3.0", "resend": "^4.0.0", "sonner": "^1.5.0", "tailwind-merge": "^2.5.2", From 5208592b06ec74088bd8780fb15d3fee0cdfc913 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 10:37:25 +0530 Subject: [PATCH 05/35] Refactor email-template.tsx to add email verification functionality --- emails/email-template.tsx | 129 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 emails/email-template.tsx diff --git a/emails/email-template.tsx b/emails/email-template.tsx new file mode 100644 index 0000000..d2f0df4 --- /dev/null +++ b/emails/email-template.tsx @@ -0,0 +1,129 @@ +import * as React from "react"; +import { + Body, + Container, + Head, + Html, + Preview, + Section, + Text, + Heading, + Button, +} from "@react-email/components"; + +interface EmailTemplateProps { + name: string; + email: string; + OTP: string; +} + +export const EmailTemplate = ({ name, OTP }: EmailTemplateProps) => ( + + + Your OTP for Tedx 2024 Email Verification + + + Tedx SJEC + Hello {name}, + + Thank you for registering for Tedx 2024. + + + Your One-Time Password (OTP) for email verification is: + +
+ {OTP} +
+ + Please enter this OTP to complete your registration. The OTP is valid + for 10 minutes. + +
+ +
+ Thank you! + + Tedx SJEC Team + +
+ + +); + +export default EmailTemplate; + +const main = { + backgroundColor: "#ffffff", + fontFamily: "HelveticaNeue,Helvetica,Arial,sans-serif", + textAlign: "center" as const, +}; + +const container = { + backgroundColor: "#ffffff", + border: "1px solid #ddd", + borderRadius: "5px", + marginTop: "20px", + width: "480px", + maxWidth: "100%", + margin: "0 auto", + padding: "12% 6%", +}; + +const company = { + fontWeight: "bold", + fontSize: "18px", + textAlign: "center" as const, +}; + +const codeTitle = { + textAlign: "center" as const, +}; + +const codeDescription = { + textAlign: "center" as const, +}; + +const codeContainer = { + background: "rgba(0,0,0,.05)", + borderRadius: "4px", + margin: "16px auto 14px", + verticalAlign: "middle", + width: "280px", + maxWidth: "100%", +}; + +const codeStyle = { + color: "#000", + display: "inline-block", + paddingBottom: "8px", + paddingTop: "8px", + margin: "0 auto", + width: "100%", + textAlign: "center" as const, + letterSpacing: "8px", +}; + +const buttonContainer = { + margin: "27px auto", + width: "auto", +}; + +const button = { + backgroundColor: "red", + borderRadius: "3px", + fontWeight: "600", + color: "#fff", + textAlign: "center" as const, + padding: "12px 24px", + margin: "0 auto", +}; + +const paragraph = { + color: "#444", + letterSpacing: "0", + padding: "0 40px", + margin: "0", + textAlign: "center" as const, +}; From 8904e526a3817825fb84eeaddf4c6fff44bbd436 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 10:37:31 +0530 Subject: [PATCH 06/35] Refactor email-template.tsx to add TEDxSJEC Talk registration confirmation email functionality --- emails/user-registration-email-template.tsx | 88 +++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 emails/user-registration-email-template.tsx diff --git a/emails/user-registration-email-template.tsx b/emails/user-registration-email-template.tsx new file mode 100644 index 0000000..9998f99 --- /dev/null +++ b/emails/user-registration-email-template.tsx @@ -0,0 +1,88 @@ +import { tedxsjecAssetsPrefix } from "@/lib/utils"; +import { + Body, + Button, + Container, + Head, + Heading, + Hr, + Html, + Img, + Preview, + Section, + Text, +} from "@react-email/components"; +import { Tailwind } from "@react-email/tailwind"; + +interface TedxRegistrationEmailProps { + name?: string; + registrationLink: string; +} + +export const TedxRegistrationEmail = ({ name, registrationLink }: TedxRegistrationEmailProps) => { + const previewText = `TEDxSJEC Talk Registration Successful!`; + + return ( + + + {previewText} + + + + {/* Logo Section */} +
+ TEDxSJEC Logo +
+ {/* Heading Section */} +
+ + TEDxSJEC Talk Registration Confirmed! + +
+ + Dear {name ?? "Participant"}, + + + We are excited to confirm your registration for TEDxSJEC Talk.
+ You are all set to join us for an inspiring day filled with ideas worth sharing. + Please bring this email on the event day for a smooth entry process. +
+ {/* QR Code Section */} +
+ + Below is your unique QR code for registration. Kindly keep it accessible on + event day for quick check-in: + + QR Code +
+ + We look forward to seeing you at TEDxSJEC!
+
+
+ + Thanks & Regards,
TEDxSJEC Team
+ For any queries, feel free to contact us at: tedxsjec@sjec.ac.in +
+
+ +  |  + +  |  + +
+
+ +
+ + ); +}; + +export default TedxRegistrationEmail; From 191ce7b0c872bcf2aa1687a76a0be4b80d2a6680 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 10:37:42 +0530 Subject: [PATCH 07/35] Refactor create-order route to use razorpay library for order creation --- src/app/api/create-order/route.ts | 59 ++++++++++++++----------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/src/app/api/create-order/route.ts b/src/app/api/create-order/route.ts index 86a01a4..6d35e7e 100644 --- a/src/app/api/create-order/route.ts +++ b/src/app/api/create-order/route.ts @@ -1,37 +1,32 @@ import { NextRequest, NextResponse } from "next/server"; -import Razorpay from "razorpay"; - -const razorpay = new Razorpay({ - key_id: process.env.RAZORPAY_KEY_ID!, - key_secret: process.env.RAZORPAY_KEY_SECRET!, -}); +import { razorpay } from "@/lib/razorpay"; export async function POST(request: NextRequest) { - const { amount } = await request.json(); - try { - const order = await razorpay.orders.create({ - amount: amount * 100, - currency: "INR", - receipt: "receipt_" + Math.random().toString(36).substring(7), - }); + const { amount } = await request.json(); + try { + const order = await razorpay.orders.create({ + amount: amount * 100, + currency: "INR", + receipt: "receipt_" + Math.random().toString(36).substring(7), + }); - return NextResponse.json( - { - orderId: order.id, - }, - { - status: 200, - }, - ); - } catch (error) { - console.log(error); - return NextResponse.json( - { - error: "Error creating order ", - }, - { - status: 500, - }, - ); - } + return NextResponse.json( + { + orderId: order.id, + }, + { + status: 200, + } + ); + } catch (error) { + console.log(error); + return NextResponse.json( + { + error: "Error creating order ", + }, + { + status: 500, + } + ); + } } From f256be51fa0ad169a9a8749a583fd104d20c963f Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 10:38:05 +0530 Subject: [PATCH 08/35] create api route to verify the order --- src/app/api/verify-order/route.ts | 42 +++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/app/api/verify-order/route.ts b/src/app/api/verify-order/route.ts index 72d2b82..7cb73be 100644 --- a/src/app/api/verify-order/route.ts +++ b/src/app/api/verify-order/route.ts @@ -2,6 +2,7 @@ import { NextRequest, NextResponse } from "next/server"; import crypto from "crypto"; import { getServerSideSession } from "@/lib/get-server-session"; import prisma from "@/server/db"; +import { sendRegistrationEmail } from "@/lib/send-registration-email"; const generatedSignature = (razorpayOrderId: string, razorpayPaymentId: string) => { const keySecret = process.env.RAZORPAY_KEY_SECRET!; @@ -16,21 +17,40 @@ const generatedSignature = (razorpayOrderId: string, razorpayPaymentId: string) export async function POST(request: NextRequest) { const { orderId, razorpayPaymentId, razorpaySignature, amount } = await request.json(); const session = await getServerSideSession(); - if(!session){ + if (!session) { return NextResponse.json({ message: "No session", isOk: false }, { status: 400 }); } const signature = generatedSignature(orderId, razorpayPaymentId); if (signature !== razorpaySignature) { return NextResponse.json({ message: "payment verification failed", isOk: false }, { status: 400 }); } - await prisma.payment.create({ - data: { - signature: razorpaySignature as string, - userId: session?.user.id!, - amount, - orderCreationId: orderId, - razorpayPaymentId: razorpayPaymentId, - }, - }); - return NextResponse.json({ message: "payment verified successfully", isOk: true }, { status: 200 }); + if (signature === razorpaySignature) { + const user = await prisma.user.findUnique({ + where: { + email: session.user?.email!, + }, + }); + + try { + await sendRegistrationEmail({ + email: session.user?.email!, + name: session.user?.name!, + registrationLink: `http://localhost:3000/verify/${razorpayPaymentId}`, + }); + } catch (error) { + console.log(error); + } + await prisma.$transaction(async (prisma) => { + await prisma.payment.create({ + data: { + amount: amount, + orderCreationId: orderId, + razorpayPaymentId: razorpayPaymentId, + signature: razorpaySignature, + user: { connect: { email: session.user?.email! } }, + }, + }); + }); + return NextResponse.json({ message: "payment verified successfully", isOk: true }, { status: 200 }); + } } From 6072a6a8314713f181212c83aeec6aeec79582c4 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 10:38:17 +0530 Subject: [PATCH 09/35] Add API route to verify order --- src/app/api/verify-order/[id]/route.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/app/api/verify-order/[id]/route.ts diff --git a/src/app/api/verify-order/[id]/route.ts b/src/app/api/verify-order/[id]/route.ts new file mode 100644 index 0000000..e43540b --- /dev/null +++ b/src/app/api/verify-order/[id]/route.ts @@ -0,0 +1,22 @@ +import { getServerSideSession } from "@/lib/get-server-session"; +import { razorpay } from "@/lib/razorpay"; +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(request: Request, context: { params: { id: string } }) { + const session = await getServerSideSession(); + if (!session) { + return NextResponse.json({ message: "Unauthorized", isOk: false }, { status: 401 }); + } + if (session.user.role !== "ADMIN") { + return NextResponse.json({ message: "Forbidden", isOk: false }, { status: 403 }); + } + + const { id } = context.params; + try { + const paymentData = await razorpay.payments.fetch(id); + return NextResponse.json(paymentData, { status: 200 }); + } catch (error) { + console.error("Error fetching payment data:", error); + return NextResponse.json({ error: "Payment not found" }, { status: 404 }); + } +} From d342eb708570f756fada15107ac49bed99eb50ed Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 10:38:57 +0530 Subject: [PATCH 10/35] Refactor HorizontalScrollCarousel component to use TEDxSJEC team data and update image URLs --- src/components/HorizontalScrollCarousel.tsx | 179 ++++++++++---------- 1 file changed, 89 insertions(+), 90 deletions(-) diff --git a/src/components/HorizontalScrollCarousel.tsx b/src/components/HorizontalScrollCarousel.tsx index 661b919..196113f 100644 --- a/src/components/HorizontalScrollCarousel.tsx +++ b/src/components/HorizontalScrollCarousel.tsx @@ -1,112 +1,111 @@ +import { tedxsjecAssetsPrefix } from "@/lib/utils"; import { motion, useTransform, useScroll } from "framer-motion"; import { useRef } from "react"; const HorizontalScroll = () => { - return ( -
- -
- ); + return ( +
+ +
+ ); }; const HorizontalScrollCarousel = () => { - const targetRef = useRef(null); - const { scrollYProgress } = useScroll({ - target: targetRef, - }); + const targetRef = useRef(null); + const { scrollYProgress } = useScroll({ + target: targetRef, + }); - const x = useTransform(scrollYProgress, [0, 1], ["5%", "-50%"]); + const x = useTransform(scrollYProgress, [0, 1], ["5%", "-50%"]); - return ( -
-
- -

- The Team -

- {cards.map((card) => { - return ; - })} -
-
-
- ); + return ( +
+
+ +

The Team

+ {cards.map((card) => { + return ; + })} +
+
+
+ ); }; const Card = ({ card }: { card: CardType }) => { - return ( -
-
-
-
-

{card.name}

-

{card.title}

+ return ( +
+
+
+
+

{card.name}

+

{card.title}

+
+
-
-
- ); + ); }; export default HorizontalScroll; type CardType = { - url: string; - title: string; - id: number; - name: string; + url: string; + title: string; + id: number; + name: string; }; const cards: CardType[] = [ - // { - // url: "https://tedx-sjec.github.io/website-assets/team/dr-binu-k-g.avif", - // title: "Faculty Co-Ordinator", - // name: "Binu K G", - // id: 1, - // }, - { - url: "https://tedx-sjec.github.io/website-assets/team/sharon.avif", - title: "Licensee & Organizer", - id: 2, - name: "Sharon Tyana Menezes", - }, - { - url: "/imgs/abstract/3.jpg", - title: "Co-Organizer", - id: 3, - name: "Sasha Sajith", - }, - { - url: "/imgs/abstract/4.jpg", - title: "Curation Head", - id: 4, - name: "Vyasa M Nayak", - }, - { - url: "/imgs/abstract/5.jpg", - title: "Technical Head", - id: 5, - name: "Hanniel Andrede", - }, - { - url: "/imgs/abstract/6.jpg", - title: "Design Head", - id: 6, - name: "Lawrence Robert D'Souza", - }, - // { - // url: "/imgs/abstract/7.jpg", - // title: "Title 7", - // id: 7, - // name: "Binu K G", - // }, + // { + // url: "https://tedx-sjec.github.io/website-assets/team/dr-binu-k-g.avif", + // title: "Faculty Co-Ordinator", + // name: "Binu K G", + // id: 1, + // }, + { + url: `${tedxsjecAssetsPrefix}/team/sharon.avif`, + title: "Licensee & Organizer", + id: 2, + name: "Sharon Tyana Menezes", + }, + { + url: "/imgs/abstract/3.jpg", + title: "Co-Organizer", + id: 3, + name: "Sasha Sajith", + }, + { + url: "/imgs/abstract/4.jpg", + title: "Curation Head", + id: 4, + name: "Vyasa M Nayak", + }, + { + url: "/imgs/abstract/5.jpg", + title: "Technical Head", + id: 5, + name: "Hanniel Andrede", + }, + { + url: "/imgs/abstract/6.jpg", + title: "Design Head", + id: 6, + name: "Lawrence Robert D'Souza", + }, + // { + // url: "/imgs/abstract/7.jpg", + // title: "Title 7", + // id: 7, + // name: "Binu K G", + // }, ]; From 13e16c05bb845030611ca598e21d06e4825f43bc Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 10:39:06 +0530 Subject: [PATCH 11/35] Refactor email-template.tsx to remove unused code and update styling --- src/lib/email-template.tsx | 129 ------------------------------------- 1 file changed, 129 deletions(-) delete mode 100644 src/lib/email-template.tsx diff --git a/src/lib/email-template.tsx b/src/lib/email-template.tsx deleted file mode 100644 index d2f0df4..0000000 --- a/src/lib/email-template.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import * as React from "react"; -import { - Body, - Container, - Head, - Html, - Preview, - Section, - Text, - Heading, - Button, -} from "@react-email/components"; - -interface EmailTemplateProps { - name: string; - email: string; - OTP: string; -} - -export const EmailTemplate = ({ name, OTP }: EmailTemplateProps) => ( - - - Your OTP for Tedx 2024 Email Verification - - - Tedx SJEC - Hello {name}, - - Thank you for registering for Tedx 2024. - - - Your One-Time Password (OTP) for email verification is: - -
- {OTP} -
- - Please enter this OTP to complete your registration. The OTP is valid - for 10 minutes. - -
- -
- Thank you! - - Tedx SJEC Team - -
- - -); - -export default EmailTemplate; - -const main = { - backgroundColor: "#ffffff", - fontFamily: "HelveticaNeue,Helvetica,Arial,sans-serif", - textAlign: "center" as const, -}; - -const container = { - backgroundColor: "#ffffff", - border: "1px solid #ddd", - borderRadius: "5px", - marginTop: "20px", - width: "480px", - maxWidth: "100%", - margin: "0 auto", - padding: "12% 6%", -}; - -const company = { - fontWeight: "bold", - fontSize: "18px", - textAlign: "center" as const, -}; - -const codeTitle = { - textAlign: "center" as const, -}; - -const codeDescription = { - textAlign: "center" as const, -}; - -const codeContainer = { - background: "rgba(0,0,0,.05)", - borderRadius: "4px", - margin: "16px auto 14px", - verticalAlign: "middle", - width: "280px", - maxWidth: "100%", -}; - -const codeStyle = { - color: "#000", - display: "inline-block", - paddingBottom: "8px", - paddingTop: "8px", - margin: "0 auto", - width: "100%", - textAlign: "center" as const, - letterSpacing: "8px", -}; - -const buttonContainer = { - margin: "27px auto", - width: "auto", -}; - -const button = { - backgroundColor: "red", - borderRadius: "3px", - fontWeight: "600", - color: "#fff", - textAlign: "center" as const, - padding: "12px 24px", - margin: "0 auto", -}; - -const paragraph = { - color: "#444", - letterSpacing: "0", - padding: "0 40px", - margin: "0", - textAlign: "center" as const, -}; From 56b12841eb1add67c22de9d9a0109cb7183dd4c5 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 10:39:12 +0530 Subject: [PATCH 12/35] Add razorpay.ts to integrate Razorpay payment gateway --- src/lib/razorpay.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/lib/razorpay.ts diff --git a/src/lib/razorpay.ts b/src/lib/razorpay.ts new file mode 100644 index 0000000..807098e --- /dev/null +++ b/src/lib/razorpay.ts @@ -0,0 +1,6 @@ +import Razorpay from "razorpay"; + +export const razorpay = new Razorpay({ + key_id: process.env.RAZORPAY_KEY_ID!, + key_secret: process.env.RAZORPAY_KEY_SECRET!, +}); From 16055139620dcfcfe9ef16a5308daca0c3328ddc Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 10:39:22 +0530 Subject: [PATCH 13/35] Refactor resend-mailer.ts to use updated EmailTemplate path and remove console.log statements --- src/lib/resend-mailer.ts | 46 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/lib/resend-mailer.ts b/src/lib/resend-mailer.ts index 201c9e5..1aaa68b 100644 --- a/src/lib/resend-mailer.ts +++ b/src/lib/resend-mailer.ts @@ -1,32 +1,32 @@ -import { EmailTemplate } from "./email-template"; +import { EmailTemplate } from "../../emails/email-template"; import { ResendEmailOptions, sendEmail as SendEmailType } from "@/types"; import { Resend } from "resend"; const resend = new Resend(process.env.RESEND_API_KEY); export async function MailUsingResend({ email, name, OTP }: SendEmailType) { - console.log(process.env.RESEND_API_KEY); - try { - const mailOptions: ResendEmailOptions = { - from: '"Tedx SJEC" ', - to: email, - subject: "Tedx SJEC - Your OTP for Email Verification", - react: EmailTemplate({ - name: name, - OTP: OTP, - email: email, - }), - text: `Hello ${name},\n\nThank you for registering for Tedx 2024.\n\nYour One-Time Password (OTP) for email verification is:\n\n${OTP}\n\nPlease enter this OTP to complete your registration. The OTP is valid for 10 minutes.\n\nThank you!\n\nTedx SJEC Team`, - }; + console.log(process.env.RESEND_API_KEY); + try { + const mailOptions: ResendEmailOptions = { + from: '"Tedx SJEC" ', + to: email, + subject: "Tedx SJEC - Your OTP for Email Verification", + react: EmailTemplate({ + name: name, + OTP: OTP, + email: email, + }), + text: `Hello ${name},\n\nThank you for registering for Tedx 2024.\n\nYour One-Time Password (OTP) for email verification is:\n\n${OTP}\n\nPlease enter this OTP to complete your registration. The OTP is valid for 10 minutes.\n\nThank you!\n\nTedx SJEC Team`, + }; - const { data, error } = await resend.emails.send(mailOptions); - console.log(data, error); - if (error) { - return { error, status: 500 }; - } + const { data, error } = await resend.emails.send(mailOptions); + console.log(data, error); + if (error) { + return { error, status: 500 }; + } - return { data, status: 200 }; - } catch (error) { - return { error, status: 500 }; - } + return { data, status: 200 }; + } catch (error) { + return { error, status: 500 }; + } } From ec361dbf99eb5c5cb895ed6f5f91f2851bdc155e Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 10:39:30 +0530 Subject: [PATCH 14/35] Refactor send-registration-email.ts and sendMail.tsx to update email templates and remove unused code --- src/lib/send-registration-email.ts | 27 ++++++++++++++++ src/lib/sendMail.tsx | 52 ++++++++++++++---------------- 2 files changed, 51 insertions(+), 28 deletions(-) create mode 100644 src/lib/send-registration-email.ts diff --git a/src/lib/send-registration-email.ts b/src/lib/send-registration-email.ts new file mode 100644 index 0000000..4d1cc1d --- /dev/null +++ b/src/lib/send-registration-email.ts @@ -0,0 +1,27 @@ +import { TedxRegistrationEmail } from "../../emails/user-registration-email-template"; +import { Resend } from "resend"; +import { ResendEmailOptions } from "@/types"; + +const resend = new Resend(process.env.RESEND_API_KEY); + +export async function sendRegistrationEmail({ + email, + name, + registrationLink, +}: { + email: string; + name: string; + registrationLink: string; +}) { + try { + await resend.emails.send({ + from: '"Tedx SJEC" ', + to: email, + subject: "Tedx SJEC - Email Verification", + react: TedxRegistrationEmail({ name, registrationLink }), + text: `Hello ${name},\n\nThank you for registering for Tedx 2024.\n\nPlease click on the link below to complete your registration.\n\n${registrationLink}\n\nThank you!\n\nTedx SJEC Team`, + }); + } catch (error) { + console.log(error); + } +} diff --git a/src/lib/sendMail.tsx b/src/lib/sendMail.tsx index 9d67326..c667aea 100644 --- a/src/lib/sendMail.tsx +++ b/src/lib/sendMail.tsx @@ -1,38 +1,34 @@ -import { EmailTemplate } from "./email-template"; +import { EmailTemplate } from "../../emails/email-template"; import { renderAsync } from "@react-email/render"; import { EmailOptions, sendEmail as SendEmailType } from "@/types"; import nodemailer from "nodemailer"; export const sendEmail = async (options: SendEmailType) => { - try { - const transporter = nodemailer.createTransport({ - service: "gmail", - auth: { - user: process.env.GMAIL_USER, - pass: process.env.GMAIL_PASS, - }, - }); + try { + const transporter = nodemailer.createTransport({ + service: "gmail", + auth: { + user: process.env.GMAIL_USER, + pass: process.env.GMAIL_PASS, + }, + }); - const emailHtml = await renderAsync( - , - ); + const emailHtml = await renderAsync( + + ); - const mailOptions: EmailOptions = { - from: `"Tedx SJEC" <${process.env.GMAIL_USER}>`, - to: options.email, - subject: "Tedx SJEC - Your OTP for Email Verification", - html: emailHtml, - text: `Hello ${options.name},\n\nThank you for registering for Tedx 2024.\n\nYour One-Time Password (OTP) for email verification is:\n\n${options.OTP}\n\nPlease enter this OTP to complete your registration. The OTP is valid for 10 minutes.\n\nThank you!\n\nTedx SJEC Team`, - }; - const mailResponse = await transporter.sendMail(mailOptions); - return { mailResponse, status: 200 }; - } catch (error) { - return { error, status: 500 }; - } + const mailOptions: EmailOptions = { + from: `"Tedx SJEC" <${process.env.GMAIL_USER}>`, + to: options.email, + subject: "Tedx SJEC - Your OTP for Email Verification", + html: emailHtml, + text: `Hello ${options.name},\n\nThank you for registering for Tedx 2024.\n\nYour One-Time Password (OTP) for email verification is:\n\n${options.OTP}\n\nPlease enter this OTP to complete your registration. The OTP is valid for 10 minutes.\n\nThank you!\n\nTedx SJEC Team`, + }; + const mailResponse = await transporter.sendMail(mailOptions); + return { mailResponse, status: 200 }; + } catch (error) { + return { error, status: 500 }; + } }; export default sendEmail; From 29ab34bdf1ea908e8d0db303f9f0c5c836ed467c Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 10:39:38 +0530 Subject: [PATCH 15/35] Refactor utils.ts to update cn function and add tedxsjecAssetsPrefix constant --- src/lib/utils.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index a5ef193..bd2941b 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -2,5 +2,7 @@ import { clsx, type ClassValue } from "clsx"; import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); + return twMerge(clsx(inputs)); } + +export const tedxsjecAssetsPrefix = "https://tedx-sjec.github.io/website-assets"; From 81040a980f62978fc61c4058f29d6ed10ce0ec1d Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 12:23:41 +0530 Subject: [PATCH 16/35] Update package dependencies --- package-lock.json | 154 +++++++++++++++++++++++++++++++++++++++++++--- package.json | 2 + 2 files changed, 147 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 689a8c9..077f960 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,6 +54,7 @@ "react-email": "^3.0.1", "react-hook-form": "^7.53.0", "react-icons": "^5.3.0", + "react-qr-reader": "^3.0.0-beta-1", "resend": "^4.0.0", "sonner": "^1.5.0", "tailwind-merge": "^2.5.2", @@ -69,6 +70,7 @@ "@types/otp-generator": "^4.0.2", "@types/react": "^18", "@types/react-dom": "^18", + "@types/react-qr-reader": "^2.1.7", "eslint": "^8", "eslint-config-next": "14.2.6", "postcss": "^8", @@ -3526,7 +3528,6 @@ "version": "8.17.9", "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.17.9.tgz", "integrity": "sha512-uZclikSqDdI15D0t8l8F8fyRyzl6BYwUOlEke2BIjAsjVzQy5MQPROVEc/9/Ef/PAezfl6lrLulMlYwgS1JGIg==", - "license": "MIT", "peer": true, "dependencies": { "@babel/runtime": "^7.17.8", @@ -3591,7 +3592,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "peer": true, "dependencies": { "base64-js": "^1.3.1", @@ -3602,7 +3602,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "license": "MIT", "peer": true }, "node_modules/@rushstack/eslint-patch": { @@ -3764,7 +3763,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/@types/debounce/-/debounce-1.2.4.tgz", "integrity": "sha512-jBqiORIzKDOToaF63Fm//haOCHuwQuLa2202RK4MozpA6lh93eCBc+/8+wZn5OzjJt3ySdc+74SXWXB55Ewtyw==", - "license": "MIT", "peer": true }, "node_modules/@types/draco3d": { @@ -3888,11 +3886,19 @@ "@types/react": "*" } }, + "node_modules/@types/react-qr-reader": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@types/react-qr-reader/-/react-qr-reader-2.1.7.tgz", + "integrity": "sha512-6K6DQeqP7c2oohcfvBpExlOawVsB2/C+7ZZL/fkCkNzYYAKDJnNHnuP3F5ChMl0mpoYEdqkqkllxqfM0VslEiw==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-reconciler": { "version": "0.26.7", "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.7.tgz", "integrity": "sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ==", - "license": "MIT", "peer": true, "dependencies": { "@types/react": "*" @@ -3914,7 +3920,6 @@ "version": "0.169.0", "resolved": "https://registry.npmjs.org/@types/three/-/three-0.169.0.tgz", "integrity": "sha512-oan7qCgJBt03wIaK+4xPWclYRPG9wzcg7Z2f5T8xYTNEF95kh0t0lklxLLYBDo7gQiGLYzE6iF4ta7nXF2bcsw==", - "license": "MIT", "peer": true, "dependencies": { "@tweenjs/tween.js": "~23.1.3", @@ -4176,9 +4181,39 @@ "version": "0.1.47", "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.47.tgz", "integrity": "sha512-vOUHDxj0azl7BSj4YAy6cc6q5s7F1KfF5GI1er/w6togN0MqzS/d8U+H0LH1XpLbFup+UaA7aMtia/aSx3DE0w==", - "license": "BSD-3-Clause", "peer": true }, + "node_modules/@zxing/browser": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@zxing/browser/-/browser-0.0.7.tgz", + "integrity": "sha512-AepzMgDnD6EjxewqmXpHJsi4S3Gw9ilZJLIbTf6fWuWySEcHBodnGu3p7FWlgq1Sd5QyfPhTum5z3CBkkhMVng==", + "optionalDependencies": { + "@zxing/text-encoding": "^0.9.0" + }, + "peerDependencies": { + "@zxing/library": "^0.18.3" + } + }, + "node_modules/@zxing/library": { + "version": "0.18.6", + "resolved": "https://registry.npmjs.org/@zxing/library/-/library-0.18.6.tgz", + "integrity": "sha512-bulZ9JHoLFd9W36pi+7e7DnEYNJhljYjZ1UTsKPOoLMU3qtC+REHITeCRNx40zTRJZx18W5TBRXt5pq2Uopjsw==", + "dependencies": { + "ts-custom-error": "^3.0.0" + }, + "engines": { + "node": ">= 10.4.0" + }, + "optionalDependencies": { + "@zxing/text-encoding": "~0.9.0" + } + }, + "node_modules/@zxing/text-encoding": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz", + "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==", + "optional": true + }, "node_modules/abbrev": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", @@ -7956,7 +7991,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.2.5.tgz", "integrity": "sha512-fXtDA0X0t0eBYAGLVM5YsgJGsJ5jEmqZEPrGbzdf5awjv0xE7nqv3TVnvtUF060Tkes15DbDAKW/I48vsb6SyA==", - "license": "MIT", "peer": true, "dependencies": { "@types/react-reconciler": "^0.28.0" @@ -7969,7 +8003,6 @@ "version": "0.28.8", "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.8.tgz", "integrity": "sha512-SN9c4kxXZonFhbX4hJrZy37yw9e7EIxcpHCxQv5JUS18wDE5ovkQKlqQEkufdJCCMfuI9BnjUJvhYeJ9x5Ra7g==", - "license": "MIT", "peer": true, "dependencies": { "@types/react": "*" @@ -10109,6 +10142,14 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pirates": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", @@ -10972,6 +11013,20 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" }, + "node_modules/react-qr-reader": { + "version": "3.0.0-beta-1", + "resolved": "https://registry.npmjs.org/react-qr-reader/-/react-qr-reader-3.0.0-beta-1.tgz", + "integrity": "sha512-5HeFH9x/BlziRYQYGK2AeWS9WiKYZtGGMs9DXy3bcySTX3C9UJL9EwcPnWw8vlf7JP4FcrAlr1SnZ5nsWLQGyw==", + "dependencies": { + "@zxing/browser": "0.0.7", + "@zxing/library": "^0.18.3", + "rollup": "^2.67.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + } + }, "node_modules/react-reconciler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz", @@ -11055,6 +11110,14 @@ } } }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -11150,6 +11213,14 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resend": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resend/-/resend-4.0.0.tgz", @@ -11285,6 +11356,20 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rollup": { + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -12056,6 +12141,25 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/three": { "version": "0.169.0", "resolved": "https://registry.npmjs.org/three/-/three-0.169.0.tgz", @@ -12091,6 +12195,11 @@ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==" }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -12149,6 +12258,14 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-custom-error": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.3.1.tgz", + "integrity": "sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -12509,6 +12626,14 @@ "node": ">=10.12.0" } }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -12787,6 +12912,17 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/yaml": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index ffc2f92..11db89b 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "react-email": "^3.0.1", "react-hook-form": "^7.53.0", "react-icons": "^5.3.0", + "react-qr-reader": "^3.0.0-beta-1", "resend": "^4.0.0", "sonner": "^1.5.0", "tailwind-merge": "^2.5.2", @@ -74,6 +75,7 @@ "@types/otp-generator": "^4.0.2", "@types/react": "^18", "@types/react-dom": "^18", + "@types/react-qr-reader": "^2.1.7", "eslint": "^8", "eslint-config-next": "14.2.6", "postcss": "^8", From 328f7cdea1c1f95ddf4abd679b43d4015a969dd4 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 12:24:47 +0530 Subject: [PATCH 17/35] Refactor Payment table schema to update column names and constraints --- prisma/dev.db | Bin 102400 -> 102400 bytes prisma/dev.db-journal | Bin 29240 -> 29240 bytes .../20241002051550_fix_typo/migration.sql | 27 ++++++++++++++++++ prisma/schema.prisma | 4 +-- 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 prisma/migrations/20241002051550_fix_typo/migration.sql diff --git a/prisma/dev.db b/prisma/dev.db index 9628b639bbfcbb5da90c7470d5eb72773d8bd863..7599d163c2bb8caa622dff2b3a74031786895ffe 100644 GIT binary patch delta 641 zcmZozz}B#UZGyDmE(Qh$Ngx&nViq9Qo2X;VxNBp=5`GCTE;k1LLcRxle!RPQrFpu! z|8VDW-QsfFtSF$xRo^Jc#TDAf%WBQQz{;6yoSKqkZfc;Lm}G9OYhqz)uA5|#WTtCq zW^Qg_WNKz|?fXpwAeZenPVW|?G}W}1?0ZeU@MXr5+bWNvJhmS_Rg zVP;NBLgF#Rs$nZ15-m&Q-k=l%!>Gu%7T2b ztn=nuQd+DMTzu&ae2@4|___Jp_$KhB^X=r1a)QVSTk<+<`W-|;Ty+{sxeu#L}{{%D=Ra0RF@w7W^P3LlBw3@!pjZs6bB@ALiiyx4dmS*fI2HOO+1xkrcKj^|}LcqN3 zK=XF6urV+&7DO6P{?970eTp|DHzS*=7Mr-IGDtuh$p}*>3F1c$SHgcROPMBcFgEFHj{95W{G$&4LCG_!l_{01*Hm CG_Xzp delta 544 zcmZozz}B#UZGyDmHUTT)uAVw`*v82BFXoA7h;yO?t?uN~V*UQw3CJok7Vx#w+Ha9~tpnrtB8X4V>~z%DK;%h=6d zl9-f}nwMH0@0MSb3!{0QgIpa$TopnboqSvslwiV>6_|7TB~XfI`aTy%6P7ff11B?b zN>1l@WxU7eIenosqvCWs7e=G$|2-I;c%h2pLCQQQC$fvNf?3lOTo^4TzhmXz{?U!G zm4%I$moX#Kc=CT%iS1Lo8MzrO+R%NDTrWPsbC@AHZ6ewxBim{1D8Z$Cv=B1=o z6c^@X`m3{vtBNufg9Sh#6<=DM7oVM4>87i}ChjN=GH*JIFQWiAFECCyfS5sDZSs0v nneE2DjAxk`xwbO~F!BiqN&qFqfEc8T2Z*_Vk@tXqQGfyf*I}G~ diff --git a/prisma/dev.db-journal b/prisma/dev.db-journal index 8f0ec3fbeeed2d258737a7eabcdbfd48d80d5091..bbef202b6aa137e0183b755fe9a2317526bb52d0 100644 GIT binary patch literal 29240 zcmeHO-)|g89luLrJHFU)swx=NM!lW{tx>j}nVsF)p#tIBo64%=B>n*j5?W?wW|M1d zpL=(1V7jQS&&7k;>c$@AR^Rh#sh&=mX+^ake`ck zOc+s0C`q=&&W7G>+qTC#6DKVsYzY!16kIEhM}z@ENP2=Y>Zy!(Irxq*Z@32mXtc5Bnt z|FknPwhIR_syNNCmql246d|w|kElmkMl=-+#z;{R5XyK2FVgTc41~Zq^+V|^1>|t% z`x2O;SV<`(m<&gPW?>WxMo6kT4Ew|Oo4ar@3s};wZ`t}kbtXqG9N(}L5-fZgNH60& z^5Bg|K8$-Q2_yr{VX7#`NC=c-Avuer<^)9;#sx*mAVX4WNeMFgsKC(0Gmk5pc_3(&$t)ES z^)XVEM;yUj5zMh*G*Ym9IM4hv0EiitC{>K5DOWxwOlzThi4m71WnjI#?|gmddp&rt zR4D7gvyCrwrjA=o%up8LNJF6>AOJ=AGVnObK<_kzAp#!}5Vz(b5`a;|u&}(cAOKpB zhE*3bP>$d@iU}irD`$`KJzI4qe&Z;1N3ZTV|wqHF=#Js`{M-WPa; zp}?ag0BD>k4*-xfR65|kh|&OF8)!f(X~1}zNd&7cgxO*Ns*DKiOcZI@5@Ek!9Ck>g zVe2GB35q39^v1;(eo+7dNri|eoBCy2|C3+cI5!1bdU@r_V!f@aM*X5)^-E_;<#Ors z)he{T4&@V2rlFjG;^lX^*{fW9IOP6%>8Y1q8G#PvskcqHvr}(R{%rh>iTRT+kNZui=gwW43`e6{yE z*?p!qvo|$K44e3#4RjaF7bv3@aT3xyXWo>b> zdU<)_;_ULZ>htln^F<%ns9;#YHP|gf#Tea#u7-MzeV%!@ie^xfN zXls>-_K-f+`S`-@+Tv<;Zf$uvURq7e8&+0lFJ8`{-riCNKV6xLPmfMt^UEb`lh%vt zup|<(-EP?5lOePucu3{cH)l?bO`knm{!UzrJb3GEl#DqtR|8+s*aiqsYeky1uT>ijtz43nYJ~Q9^qs zIT(9WXS&%G>+tlzn1!L!onFfas)e~rODn6(vkObB)tWIyGB9A0!8)u}FI-xV7oJ-( z+O9rX8|YD+sV>JCVvyNfyi%>%RS11x7Bglqn2#4@*iPnVSLSBtV^gzs*=V|`>C&?g zL?0VNA@sHH0kE9&2$I?hVkOR(>OK^enI|Sjr=K}{kmM~f*!-Nl^Z5AK^tp58SI$~d z7sD0z%AmN5>LUqUHq-$E&zV0&3)?M-H+H3xtFPVyyMV5qy>w|Yo?Yq*sJBsMV!fsF z&V_m3)7H{&$zt+_q%5wX<{X&U2Q8=`j2<^bG4xvZ2nv{k{rgB_db%s>JCXVgUjT#{%f9g- zzU^r5&)k)nr%xV6b`J_JK8@e`@`xq-+mn{;!nY~zql07@)kh-xP$nTZKVW(HoTZ^B zRngk-J`L^I)EW2=H~LMTFKw6%NNY$#Ze8n6z)=uC7cb|JSiP8hLXJ7FhG=Y04V-#? z+A6wrm7KKN;BO2)*WS}EQ#;gw>5knm$ij#pjvz-56J!qx#Oqz(eC&2`-1mT74pa!}~f*4!1I#*(VM=vkhMfHa|zc@ul+EG{)s`C6-`_V(P68k!;kjH?5Or z!lOMk#|FvY-(kQMCM4K%+2EirCg`2H1v59ayxH0Y*LUC=h$-@}S$(tKx{*8kyS?`q zt2dk6$;>+rd*OQHI)oPcu09VK?7R*Grb6DddqUoK&ycXHn?(@P_qL)}Z^}K1$n9nm zJYh(7Z9oJjHn#E^imk165Fl(5daIS#Wnu8;I}rqD(MyJ1s4?1l3 z8!o~7>yCE=>W9aF_qD%&3_c&02Y3zIi#)(F_vDkm$7N|C8*_szTVzFsLg;JX z6Sftx6`a#94^SkwTpqw=*tUxt$xuo4TK5Rbc#=mHlgk5i^B5ma*yZv7#di_8SMBlu zCMfAYQ;LxL!x5y*1Gqdu*Q0*wSuljseGjW56-s z7;p?Y1{?#90mp!2z%k$$D3w~Dee?nFP;q|`;MCw4a11yG90QI4$ADwNG2j?*3^)cH P1CD`@J_A39AHMQ0{Sly< delta 1117 zcmb_bO=uHA6y8nKO|qL!V%p87KWV39(j>LeHXeE?2&qOWmXwABs-R1nOm%JknoX)6 zG=!Ri?Q!lE@hbkXmm(?%;z95(cqvlstvc^WM%LyR*l> zwp)A-ewT5txprMi@vS)E+!Fo>MSfS0$3FA+Chy=gO_9MrovNM@Us*jp6GcD6Ff!S6 zb?d>{Z}-^#hP_T+k|?Y*cJ7c7hWV1?Kz#0aFJ9sfMalU|6veo(Eo|!}mb;c%>lU!d zfdISZu4R`CsD$n*SIgC+c{(qr67h5bq~o*m2>_{BZ%7_?rmmqp1nI<5D-$vRHXn8b z5Y7VNhLpxXhP?PddIpbi(&IcJ3s$mfUda~A^->K25_}%N@%iz~(O+G}6d(5a@Vl_X zxPOobt+{d@;i<7GFRXXDWJzMTY`7a!FH;E=sMuib~2VdSGh2M>J)UbBmb-m`h$s zECFb0&-y{IkUY`Dh-unJw!o3Y%^<=fk%QpJ&Kw~rJA~;qN-A^RcH}Z-s|d60Ui!Y zat8;RJ<<6Z5qN?I#{ndOFq-gjG$_-iZmpm$ggH4Rv6>;E->1|ygFSjTJM>@XPFuCP zq7uRr@r2RvC@0TIEQ6&8X!PcSHhF^lmCe9Eri8W@t Date: Wed, 2 Oct 2024 12:25:27 +0530 Subject: [PATCH 18/35] add admin page to verify the payment --- src/app/admin/verify/page.tsx | 76 +++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/app/admin/verify/page.tsx diff --git a/src/app/admin/verify/page.tsx b/src/app/admin/verify/page.tsx new file mode 100644 index 0000000..13dfa50 --- /dev/null +++ b/src/app/admin/verify/page.tsx @@ -0,0 +1,76 @@ +"use client"; + +import { useState, useEffect } from "react"; +import { QrReader } from "react-qr-reader"; +import { useRouter } from "next/navigation"; + +export default function QRCodeScanner() { + const [isMobile, setIsMobile] = useState(false); + const [error, setError] = useState(null); + const router = useRouter(); + + useEffect(() => { + // Check if the device is mobile + const checkMobile = () => { + const userAgent = navigator.userAgent || navigator.vendor || (window as any).opera; + return /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test( + userAgent.toLowerCase() + ); + }; + + setIsMobile(checkMobile()); + }, []); + + const handleScan = (result: string | null) => { + if (result) { + // Validate URL before redirecting + try { + new URL(result); + router.push(result); + } catch { + setError("Invalid QR code. Please scan a valid URL."); + } + } + }; + + const handleError = (error: Error) => { + setError("Error accessing camera: " + error.message); + }; + + if (!isMobile) { + return ( +
+
+

Error

+

+ This feature is only available on mobile devices. Please access this page from your + smartphone or tablet. +

+
+
+ ); + } + + return ( +
+
+

QR Code Scanner

+ {error ? ( +

{error}

+ ) : ( + { + if (result) { + handleScan(result?.text); + } + }} + constraints={{ facingMode: "environment" }} + /> + )} +

+ Position the QR code within the frame to scan. +

+
+
+ ); +} From 25540de76b3e20adc6892525999d3ae16c7b9658 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 12:27:24 +0530 Subject: [PATCH 19/35] verify using id --- src/app/admin/verify/[id]/page.tsx | 78 ++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/app/admin/verify/[id]/page.tsx diff --git a/src/app/admin/verify/[id]/page.tsx b/src/app/admin/verify/[id]/page.tsx new file mode 100644 index 0000000..f39f975 --- /dev/null +++ b/src/app/admin/verify/[id]/page.tsx @@ -0,0 +1,78 @@ +/* eslint-disable react/no-unescaped-entities */ +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" +import { Button } from "@/components/ui/button" +import { AlertCircle, CheckCircle } from "lucide-react" +import Link from "next/link" +import React from "react" +async function getPaymentData(id: string) { + // Simulate API call + const response = await fetch(`http://localhost:3000/api/verify-order/${id}`) + const data = await response.json() + if (response.status === 200) { + return data + } + return null +} + +export default async function PaymentPage({ params }: { params: { id: string } }) { + const paymentData = await getPaymentData(params.id) + + return ( +
+ + + + {paymentData ? "Payment Found" : "Payment Not Found"} + + + +
+

+ Payment details for ID: {params.id} +

+ {paymentData ? ( + <> +
+ +
+

Payment Successful

+

Your payment has been processed successfully.

+
+
+
+

Amount Paid:

+

₹{(paymentData.amount / 100).toFixed(2)}

+
+
+

Paid By:

+

{paymentData.email}

+
+ + ) : ( +
+ +
+

Payment Not Found

+

We couldn't find any payment with the provided ID.

+
+
+ )} +
+ + + +
+
+
+
+
+ ) +} \ No newline at end of file From f153e81acc54f4c2f5aa25a9397e082854ac76d3 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 12:27:30 +0530 Subject: [PATCH 20/35] Refactor API URL in admin verification page --- src/app/admin/verify/[id]/page.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/admin/verify/[id]/page.tsx b/src/app/admin/verify/[id]/page.tsx index f39f975..4dc66b8 100644 --- a/src/app/admin/verify/[id]/page.tsx +++ b/src/app/admin/verify/[id]/page.tsx @@ -6,6 +6,7 @@ import Link from "next/link" import React from "react" async function getPaymentData(id: string) { // Simulate API call + //Hardcoded the url because the other one just did'nt work const response = await fetch(`http://localhost:3000/api/verify-order/${id}`) const data = await response.json() if (response.status === 200) { From de0a2f6cd63bf4c8dea2ee6aebe38aae668d5c26 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 12:28:37 +0530 Subject: [PATCH 21/35] feat : send the email after success full registration --- src/app/api/verify-order/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/api/verify-order/route.ts b/src/app/api/verify-order/route.ts index 7cb73be..2815441 100644 --- a/src/app/api/verify-order/route.ts +++ b/src/app/api/verify-order/route.ts @@ -35,7 +35,7 @@ export async function POST(request: NextRequest) { await sendRegistrationEmail({ email: session.user?.email!, name: session.user?.name!, - registrationLink: `http://localhost:3000/verify/${razorpayPaymentId}`, + registrationLink: `http://localhost:3000/admin/verify/${razorpayPaymentId}`, }); } catch (error) { console.log(error); From 37f315d22389355b4f812a67ca9a14adc0881f26 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 12:28:43 +0530 Subject: [PATCH 22/35] Refactor authorization check in verify-order route --- src/app/api/verify-order/[id]/route.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/app/api/verify-order/[id]/route.ts b/src/app/api/verify-order/[id]/route.ts index e43540b..4739d03 100644 --- a/src/app/api/verify-order/[id]/route.ts +++ b/src/app/api/verify-order/[id]/route.ts @@ -3,13 +3,13 @@ import { razorpay } from "@/lib/razorpay"; import { NextRequest, NextResponse } from "next/server"; export async function GET(request: Request, context: { params: { id: string } }) { - const session = await getServerSideSession(); - if (!session) { - return NextResponse.json({ message: "Unauthorized", isOk: false }, { status: 401 }); - } - if (session.user.role !== "ADMIN") { - return NextResponse.json({ message: "Forbidden", isOk: false }, { status: 403 }); - } + // const session = await getServerSideSession(); + // if (!session) { + // return NextResponse.json({ message: "Unauthorized", isOk: false }, { status: 401 }); + // } + // if (session.user.role !== "ADMIN") { + // return NextResponse.json({ message: "Forbidden", isOk: false }, { status: 403 }); + // } const { id } = context.params; try { From 643627748e0fa43b8b9310edebf959bf5087285a Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 12:28:50 +0530 Subject: [PATCH 23/35] Refactor admin navbar to add a "Verify" option --- src/components/Admin/Navbar/navbar.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/components/Admin/Navbar/navbar.tsx b/src/components/Admin/Navbar/navbar.tsx index 31d6465..48692b1 100644 --- a/src/components/Admin/Navbar/navbar.tsx +++ b/src/components/Admin/Navbar/navbar.tsx @@ -55,6 +55,14 @@ const Sidebar = () => { open={open} href="/admin/payment" /> +
From 9333e88b82cf224fecfe7b5cbd247e5f7b952a92 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 14:35:56 +0530 Subject: [PATCH 24/35] Fix npm install command to force installation of dependencies --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a6f85d8..6ba98fc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: node-version: ${{ matrix.node-version }} - name: Install dependencies - run: npm install + run: npm install --force - name: Check Environment Variables run: | From 792c98fafffe0dd116e2915630bf8932d574d8f7 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 15:08:31 +0530 Subject: [PATCH 25/35] Update package dependencies --- package-lock.json | 118 +++++++++++++++++++++------------------------- package.json | 2 +- 2 files changed, 55 insertions(+), 65 deletions(-) diff --git a/package-lock.json b/package-lock.json index 077f960..85a7ae8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "@types/ioredis": "^4.28.10", "@types/lodash.debounce": "^4.0.9", "@uploadthing/react": "^7.0.2", + "@yudiel/react-qr-scanner": "^2.0.8", "axios": "^1.7.7", "bullmq": "^5.13.0", "canvas-confetti": "^1.9.3", @@ -54,7 +55,6 @@ "react-email": "^3.0.1", "react-hook-form": "^7.53.0", "react-icons": "^5.3.0", - "react-qr-reader": "^3.0.0-beta-1", "resend": "^4.0.0", "sonner": "^1.5.0", "tailwind-merge": "^2.5.2", @@ -3765,12 +3765,22 @@ "integrity": "sha512-jBqiORIzKDOToaF63Fm//haOCHuwQuLa2202RK4MozpA6lh93eCBc+/8+wZn5OzjJt3ySdc+74SXWXB55Ewtyw==", "peer": true }, + "node_modules/@types/dom-webcodecs": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.11.tgz", + "integrity": "sha512-yPEZ3z7EohrmOxbk/QTAa0yonMFkNkjnVXqbGb7D4rMr+F1dGQ8ZUFxXkyLLJuiICPejZ0AZE9Rrk9wUCczx4A==" + }, "node_modules/@types/draco3d": { "version": "1.4.10", "resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz", "integrity": "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==", "license": "MIT" }, + "node_modules/@types/emscripten": { + "version": "1.39.13", + "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.13.tgz", + "integrity": "sha512-cFq+fO/isvhvmuP/+Sl4K4jtU6E23DoivtbO4r50e3odaxAiVdbfSYRDdJ4gCdxx+3aRjhphS5ZMwIH4hFy/Cw==" + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -4183,37 +4193,19 @@ "integrity": "sha512-vOUHDxj0azl7BSj4YAy6cc6q5s7F1KfF5GI1er/w6togN0MqzS/d8U+H0LH1XpLbFup+UaA7aMtia/aSx3DE0w==", "peer": true }, - "node_modules/@zxing/browser": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@zxing/browser/-/browser-0.0.7.tgz", - "integrity": "sha512-AepzMgDnD6EjxewqmXpHJsi4S3Gw9ilZJLIbTf6fWuWySEcHBodnGu3p7FWlgq1Sd5QyfPhTum5z3CBkkhMVng==", - "optionalDependencies": { - "@zxing/text-encoding": "^0.9.0" - }, - "peerDependencies": { - "@zxing/library": "^0.18.3" - } - }, - "node_modules/@zxing/library": { - "version": "0.18.6", - "resolved": "https://registry.npmjs.org/@zxing/library/-/library-0.18.6.tgz", - "integrity": "sha512-bulZ9JHoLFd9W36pi+7e7DnEYNJhljYjZ1UTsKPOoLMU3qtC+REHITeCRNx40zTRJZx18W5TBRXt5pq2Uopjsw==", + "node_modules/@yudiel/react-qr-scanner": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@yudiel/react-qr-scanner/-/react-qr-scanner-2.0.8.tgz", + "integrity": "sha512-/7WHsdC1a/Z909J2zZxqgpUQ1iI554fZxIagucH/tFu1MhZkNIeykYI1OdZgDEwV4CzuSi+h90wwNrhmETcmRw==", "dependencies": { - "ts-custom-error": "^3.0.0" - }, - "engines": { - "node": ">= 10.4.0" + "barcode-detector": "^2.2.7", + "webrtc-adapter": "9.0.1" }, - "optionalDependencies": { - "@zxing/text-encoding": "~0.9.0" + "peerDependencies": { + "react": "^17 || ^18", + "react-dom": "^17 || ^18" } }, - "node_modules/@zxing/text-encoding": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz", - "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==", - "optional": true - }, "node_modules/abbrev": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", @@ -4718,6 +4710,15 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/barcode-detector": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/barcode-detector/-/barcode-detector-2.2.8.tgz", + "integrity": "sha512-m3YGKrcNBTYOIWD+FRDJzNU+qbVJ1xI4Th9OAZBITB4rZX13ShZVO8tnSM8ceglLV2yMovwiphr6P+SNIfjzOg==", + "dependencies": { + "@types/dom-webcodecs": "^0.1.11", + "zxing-wasm": "1.2.12" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -11013,20 +11014,6 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" }, - "node_modules/react-qr-reader": { - "version": "3.0.0-beta-1", - "resolved": "https://registry.npmjs.org/react-qr-reader/-/react-qr-reader-3.0.0-beta-1.tgz", - "integrity": "sha512-5HeFH9x/BlziRYQYGK2AeWS9WiKYZtGGMs9DXy3bcySTX3C9UJL9EwcPnWw8vlf7JP4FcrAlr1SnZ5nsWLQGyw==", - "dependencies": { - "@zxing/browser": "0.0.7", - "@zxing/library": "^0.18.3", - "rollup": "^2.67.2" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0", - "react-dom": "^16.8.0 || ^17.0.0" - } - }, "node_modules/react-reconciler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz", @@ -11356,20 +11343,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rollup": { - "version": "2.79.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", - "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=10.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -11455,6 +11428,11 @@ "loose-envify": "^1.1.0" } }, + "node_modules/sdp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.0.tgz", + "integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw==" + }, "node_modules/selderee": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz", @@ -12258,14 +12236,6 @@ "typescript": ">=4.2.0" } }, - "node_modules/ts-custom-error": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.3.1.tgz", - "integrity": "sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -12668,6 +12638,18 @@ "resolved": "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz", "integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==" }, + "node_modules/webrtc-adapter": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-9.0.1.tgz", + "integrity": "sha512-1AQO+d4ElfVSXyzNVTOewgGT/tAomwwztX/6e3totvyyzXPvXIIuUUjAmyZGbKBKbZOXauuJooZm3g6IuFuiNQ==", + "dependencies": { + "sdp": "^3.2.0" + }, + "engines": { + "node": ">=6.0.0", + "npm": ">=3.10.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -13000,6 +12982,14 @@ "optional": true } } + }, + "node_modules/zxing-wasm": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/zxing-wasm/-/zxing-wasm-1.2.12.tgz", + "integrity": "sha512-UzQvEA5Hv4Nd/jJoKq7UN/jfkQwEDMASqoi1unlXrEgOB9rseLpmNTywcv4/2d9aMqKjfczyk3T25r6DYxAb7g==", + "dependencies": { + "@types/emscripten": "^1.39.13" + } } } } diff --git a/package.json b/package.json index 11db89b..748273b 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@types/ioredis": "^4.28.10", "@types/lodash.debounce": "^4.0.9", "@uploadthing/react": "^7.0.2", + "@yudiel/react-qr-scanner": "^2.0.8", "axios": "^1.7.7", "bullmq": "^5.13.0", "canvas-confetti": "^1.9.3", @@ -59,7 +60,6 @@ "react-email": "^3.0.1", "react-hook-form": "^7.53.0", "react-icons": "^5.3.0", - "react-qr-reader": "^3.0.0-beta-1", "resend": "^4.0.0", "sonner": "^1.5.0", "tailwind-merge": "^2.5.2", From 98b17ee02e2eab386d9a19ffdb8f5b85acd10151 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 15:08:36 +0530 Subject: [PATCH 26/35] Refactor npm install command to remove the --force flag --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6ba98fc..a6f85d8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: node-version: ${{ matrix.node-version }} - name: Install dependencies - run: npm install --force + run: npm install - name: Check Environment Variables run: | From 441b20bccf10b46072aee6d320451e96eba5737c Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 15:09:04 +0530 Subject: [PATCH 27/35] Refactor QR code scanner to use @yudiel/react-qr-scanner --- src/app/admin/verify/page.tsx | 50 ++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/app/admin/verify/page.tsx b/src/app/admin/verify/page.tsx index 13dfa50..2ff48ba 100644 --- a/src/app/admin/verify/page.tsx +++ b/src/app/admin/verify/page.tsx @@ -1,10 +1,10 @@ "use client"; - import { useState, useEffect } from "react"; -import { QrReader } from "react-qr-reader"; +import { Scanner } from "@yudiel/react-qr-scanner"; import { useRouter } from "next/navigation"; +import { IDetectedBarcode } from "@yudiel/react-qr-scanner"; -export default function QRCodeScanner() { +const QRCodeScanner = () => { const [isMobile, setIsMobile] = useState(false); const [error, setError] = useState(null); const router = useRouter(); @@ -17,27 +17,34 @@ export default function QRCodeScanner() { userAgent.toLowerCase() ); }; - setIsMobile(checkMobile()); }, []); - const handleScan = (result: string | null) => { - if (result) { - // Validate URL before redirecting - try { - new URL(result); - router.push(result); - } catch { - setError("Invalid QR code. Please scan a valid URL."); + const handleScan = (detectedCodes: IDetectedBarcode[]) => { + if (detectedCodes.length > 0) { + const result = detectedCodes[0].rawValue; + if (result) { + try { + // Validate if the scanned result is a valid URL + const url = new URL(result); + // Redirect to the scanned URL + router.push(url.toString()); + } catch { + setError("Invalid QR code. Please scan a valid URL."); + } } } }; - const handleError = (error: Error) => { - setError("Error accessing camera: " + error.message); + const handleError = (error: unknown) => { + if (error instanceof Error) { + setError("Error accessing camera: " + error.message); + } else { + setError("An unknown error occurred."); + } }; - if (!isMobile) { + if (isMobile) { return (
@@ -58,12 +65,9 @@ export default function QRCodeScanner() { {error ? (

{error}

) : ( - { - if (result) { - handleScan(result?.text); - } - }} + )} @@ -73,4 +77,6 @@ export default function QRCodeScanner() {
); -} +}; + +export default QRCodeScanner; From eb97d38d5b3ae142e7de0f1a5fff9a5e8228707d Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 18:20:59 +0530 Subject: [PATCH 28/35] add route for razorpay --- src/components/Admin/Navbar/navbar.tsx | 374 ++++++++++++------------- 1 file changed, 181 insertions(+), 193 deletions(-) diff --git a/src/components/Admin/Navbar/navbar.tsx b/src/components/Admin/Navbar/navbar.tsx index 48692b1..cd56ce0 100644 --- a/src/components/Admin/Navbar/navbar.tsx +++ b/src/components/Admin/Navbar/navbar.tsx @@ -4,225 +4,213 @@ import { IconType } from "react-icons"; import { FiChevronDown, FiChevronsRight, FiUser } from "react-icons/fi"; import { RiCoupon3Line } from "react-icons/ri"; import { MdPayment } from "react-icons/md"; +import { SiTicktick } from "react-icons/si"; +import { SiRazorpay } from "react-icons/si"; import { motion } from "framer-motion"; import Link from "next/link"; export const AdminNavbar = () => { - return ( -
- - -
- ); + return ( +
+ + +
+ ); }; const Sidebar = () => { - const [open, setOpen] = useState(true); - const [selected, setSelected] = useState("Dashboard"); + const [open, setOpen] = useState(true); + const [selected, setSelected] = useState("Dashboard"); - return ( - - + return ( + + -
-
+
+
- -
- ); + +
+ ); }; const Option = ({ - Icon, - title, - selected, - setSelected, - open, - notifs, - href, + Icon, + title, + selected, + setSelected, + open, + notifs, + href, }: { - Icon: IconType; - title: string; - selected: string; - setSelected: Dispatch>; - open: boolean; - notifs?: number; - href?: string; + Icon: IconType; + title: string; + selected: string; + setSelected: Dispatch>; + open: boolean; + notifs?: number; + href?: string; }) => { - return ( - - setSelected(title)} - className={`relative flex h-10 w-full items-center rounded-md transition-colors ${ - selected === title - ? "bg-indigo-100 text-indigo-800" - : "text-slate-500 hover:bg-slate-100" - }`} - > - - - - {open && ( - - {title} - - )} + return ( + + setSelected(title)} + className={`relative flex h-10 w-full items-center rounded-md transition-colors ${ + selected === title ? "bg-indigo-100 text-indigo-800" : "text-slate-500 hover:bg-slate-100" + }`} + > + + + + {open && ( + + {title} + + )} - {notifs && open && ( - - {notifs} - - )} - - - ); + {notifs && open && ( + + {notifs} + + )} + + + ); }; const TitleSection = ({ open }: { open: boolean }) => { - return ( -
-
-
- - {open && ( - - Tedxsjec - Admin Page - - )} + return ( +
+
+
+ + {open && ( + + Tedxsjec + Admin Page + + )} +
+ {open && } +
- {open && } -
-
- ); + ); }; const Logo = () => { - // Temp logo from https://logoipsum.com/ - return ( - - - - - - - ); + // Temp logo from https://logoipsum.com/ + return ( + + + + + + + ); }; -const ToggleClose = ({ - open, - setOpen, -}: { - open: boolean; - setOpen: Dispatch>; -}) => { - return ( - setOpen((pv) => !pv)} - className="absolute bottom-0 left-0 right-0 border-t border-slate-300 transition-colors hover:bg-slate-100" - > -
- - - - {open && ( - > }) => { + return ( + - Hide - - )} -
-
- ); + onClick={() => setOpen((pv) => !pv)} + className="absolute bottom-0 left-0 right-0 border-t border-slate-300 transition-colors hover:bg-slate-100" + > +
+ + + + {open && ( + + Hide + + )} +
+ + ); }; const NavbarContent = () =>
; From ae2a4cac63041b8ac5c22a280585b93f4f7648bc Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 18:21:27 +0530 Subject: [PATCH 29/35] to validate the payment using id --- src/app/admin/razorpay/page.tsx | 74 +++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/app/admin/razorpay/page.tsx diff --git a/src/app/admin/razorpay/page.tsx b/src/app/admin/razorpay/page.tsx new file mode 100644 index 0000000..0468bc8 --- /dev/null +++ b/src/app/admin/razorpay/page.tsx @@ -0,0 +1,74 @@ +"use client"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useRouter } from "next/navigation"; +import React from "react"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; + +const formSchema = z.object({ + razorpayPaymentId: z.string().nonempty("Payment ID is required"), +}); + +const FetchRazorpayPaymentData = () => { + const form = useForm>({ + resolver: zodResolver(formSchema), + }); + const router = useRouter() + + const onSubmit = async (data: z.infer) => { + router.push(`/admin/razorpay/${data.razorpayPaymentId}`) + }; + + return ( +
+

+ Search by Razorpay Payment ID +

+
+ + ( + + Razorpay Payment ID: + + + + + Search for a payment by its Razorpay Payment ID + + + + )} + /> + + + +
+ ); +}; + +export default FetchRazorpayPaymentData; From 79ffa1ea54dff5fc98f5cd1c25d8651e50bf9a70 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 18:21:49 +0530 Subject: [PATCH 30/35] feat : to send the email to the user incase they didn't recive the email --- src/app/admin/razorpay/[id]/page.tsx | 177 +++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 src/app/admin/razorpay/[id]/page.tsx diff --git a/src/app/admin/razorpay/[id]/page.tsx b/src/app/admin/razorpay/[id]/page.tsx new file mode 100644 index 0000000..5e05abc --- /dev/null +++ b/src/app/admin/razorpay/[id]/page.tsx @@ -0,0 +1,177 @@ +"use client"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Label } from "@radix-ui/react-label"; +import React, { useEffect, useState } from "react"; +import { toast } from "sonner"; + +export interface Root { + id: string; + entity: string; + amount: number; + currency: string; + status: string; + order_id: string; + invoice_id: any; + international: boolean; + method: string; + amount_refunded: number; + refund_status: any; + captured: boolean; + description: string; + card_id: any; + bank: any; + wallet: any; + vpa: string; + email: string; + contact: string; + notes: Notes; + fee: number; + tax: number; + error_code: any; + error_description: any; + error_source: any; + error_step: any; + error_reason: any; + acquirer_data: AcquirerData; + created_at: number; + upi: Upi; +} + +export interface AcquirerData { + rrn: string; + upi_transaction_id: string; +} + +export interface Upi { + vpa: string; +} +export interface Notes { + customerName: string; + customerEmail: string; + customerContact: string; +} + +function FetchRazorpayPaymentData({ params }: { params: { id: string } }) { + const { id } = params; + const [paymentData, setPaymentData] = useState(null); + const [loading, setLoading] = useState(true); + const [loadingForButton, setLoadingForButton] = useState(false); + + async function sendEmail(paymentId: string) { + setLoadingForButton(true); + try { + const response = await fetch(`/api/send-email/${paymentId}`, { + method: "POST", + }); + + if (response.status === 200) { + toast.success("Email sent successfully", { + description: "An email has been sent to the customer", + }); + } else { + toast.error("Error", { + description: "An error occurred while sending the email", + }); + } + } catch (error) { + toast.error("Error", { + description: "An error occurred while sending the email", + }); + } finally { + // Ensure the button is enabled again after the operation + setLoadingForButton(false); + } + } + + useEffect(() => { + const fetchData = async () => { + try { + const res = await fetch(`/api/verify-order/${id}`); + const data = await res.json(); + setPaymentData(data); + } catch (error) { + console.error("Error fetching payment data:", error); + } finally { + setLoading(false); + } + }; + fetchData(); + }, [id]); + + if (loading) { + return ( +
+

Loading...

+
+ ); + } + + if (!paymentData) { + return ( +
+

No payment data found.

+
+ ); + } + + return ( +
+ + + + Payment Data of {paymentData.notes.customerName || "Unknown"} + + + + + + + + + + + + + +
+ ); +} + +export default FetchRazorpayPaymentData; From 51d7ce4cbf342dbec7ea04ef901138685b111caa Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 18:21:56 +0530 Subject: [PATCH 31/35] feat: Add route for sending email to user if they didn't receive the email --- src/app/api/send-email/[paymentId]/route.ts | 60 +++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/app/api/send-email/[paymentId]/route.ts diff --git a/src/app/api/send-email/[paymentId]/route.ts b/src/app/api/send-email/[paymentId]/route.ts new file mode 100644 index 0000000..2c00825 --- /dev/null +++ b/src/app/api/send-email/[paymentId]/route.ts @@ -0,0 +1,60 @@ +import { getServerSideSession } from "@/lib/get-server-session"; +import { razorpay } from "@/lib/razorpay"; +import { NextRequest, NextResponse } from "next/server"; +import { generatedSignature } from "../../verify-order/route"; +import prisma from "@/server/db"; +import { sendRegistrationEmail } from "@/lib/send-registration-email"; + +export async function POST(request: NextRequest, context: { params: { paymentId: string } }) { + const session = await getServerSideSession(); + if (!session) { + return NextResponse.json({ message: "Unauthorized", isOk: false }, { status: 401 }); + } + if (session.user.role !== "ADMIN") { + return NextResponse.json({ message: "Forbidden", isOk: false }, { status: 403 }); + } + + const { paymentId } = context.params; + const payment = await razorpay.payments.fetch(paymentId); + const signature = generatedSignature(payment.order_id, payment.id); + + const user = await prisma.user.findUnique({ + where: { + email: payment.email, + }, + }); + + const prismaPayment = prisma.payment.findUnique({ + where: { + razorpayPaymentId: payment.id, + }, + }); + try { + await sendRegistrationEmail({ + email: payment.email, + name: user?.name!, + registrationLink: `http://localhost:3000/admin/verify/${payment.id}`, + }); + } catch (error) { + console.log(error); + } + + if (!prismaPayment) { + await prisma.$transaction(async (prisma) => { + await prisma.payment.create({ + data: { + amount: parseFloat(payment.amount.toString()), + signature: signature, + razorpayPaymentId: payment.id, + orderCreationId: payment.order_id, + user: { + connect: { + email: session?.user.email!, + }, + }, + }, + }); + }); + } + return NextResponse.json({ message: "Payment verified successfully", isOk: true }, { status: 200 }); +} From 4e979a02ba3c07b7f66d8164c7f3335612fb2ac4 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 18:22:04 +0530 Subject: [PATCH 32/35] Refactor generatedSignature function to be exported for external use --- src/app/api/verify-order/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/api/verify-order/route.ts b/src/app/api/verify-order/route.ts index 2815441..d4bef86 100644 --- a/src/app/api/verify-order/route.ts +++ b/src/app/api/verify-order/route.ts @@ -4,7 +4,7 @@ import { getServerSideSession } from "@/lib/get-server-session"; import prisma from "@/server/db"; import { sendRegistrationEmail } from "@/lib/send-registration-email"; -const generatedSignature = (razorpayOrderId: string, razorpayPaymentId: string) => { +export const generatedSignature = (razorpayOrderId: string, razorpayPaymentId: string) => { const keySecret = process.env.RAZORPAY_KEY_SECRET!; const sig = crypto From 1bf2b46efa974081a39e50f83fbdfe71da16250f Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 18:28:29 +0530 Subject: [PATCH 33/35] Refactor generatedSignature import in send-email route --- src/app/api/send-email/[paymentId]/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/api/send-email/[paymentId]/route.ts b/src/app/api/send-email/[paymentId]/route.ts index 2c00825..0f755d5 100644 --- a/src/app/api/send-email/[paymentId]/route.ts +++ b/src/app/api/send-email/[paymentId]/route.ts @@ -1,9 +1,9 @@ import { getServerSideSession } from "@/lib/get-server-session"; import { razorpay } from "@/lib/razorpay"; import { NextRequest, NextResponse } from "next/server"; -import { generatedSignature } from "../../verify-order/route"; import prisma from "@/server/db"; import { sendRegistrationEmail } from "@/lib/send-registration-email"; +import { generatedSignature } from "@/lib/helper"; export async function POST(request: NextRequest, context: { params: { paymentId: string } }) { const session = await getServerSideSession(); From 7bca6702a00b6d330c0adae11c526a7b903084f2 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 18:28:35 +0530 Subject: [PATCH 34/35] Refactor generatedSignature import and export in send-email route --- src/app/api/verify-order/route.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/app/api/verify-order/route.ts b/src/app/api/verify-order/route.ts index d4bef86..57e5014 100644 --- a/src/app/api/verify-order/route.ts +++ b/src/app/api/verify-order/route.ts @@ -1,18 +1,10 @@ import { NextRequest, NextResponse } from "next/server"; -import crypto from "crypto"; import { getServerSideSession } from "@/lib/get-server-session"; import prisma from "@/server/db"; import { sendRegistrationEmail } from "@/lib/send-registration-email"; +import { generatedSignature } from "@/lib/helper"; -export const generatedSignature = (razorpayOrderId: string, razorpayPaymentId: string) => { - const keySecret = process.env.RAZORPAY_KEY_SECRET!; - const sig = crypto - .createHmac("sha256", keySecret) - .update(razorpayOrderId + "|" + razorpayPaymentId) - .digest("hex"); - return sig; -}; export async function POST(request: NextRequest) { const { orderId, razorpayPaymentId, razorpaySignature, amount } = await request.json(); From c3bdaece564b2bb28d8dae392923de0d4cb44405 Mon Sep 17 00:00:00 2001 From: vyshnav Date: Wed, 2 Oct 2024 18:29:49 +0530 Subject: [PATCH 35/35] add generateSignature function in helpers to reuse --- src/lib/helper.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lib/helper.ts b/src/lib/helper.ts index b7aa4e4..cebab00 100644 --- a/src/lib/helper.ts +++ b/src/lib/helper.ts @@ -1,3 +1,4 @@ +import crypto from "crypto"; export const generateCouponCode = (length: number) => { const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; @@ -10,3 +11,14 @@ export const generateCouponCode = (length: number) => { export const createCouponCode = () => { return generateCouponCode(10); }; + + +export const generatedSignature = (razorpayOrderId: string, razorpayPaymentId: string) => { + const keySecret = process.env.RAZORPAY_KEY_SECRET!; + + const sig = crypto + .createHmac("sha256", keySecret) + .update(razorpayOrderId + "|" + razorpayPaymentId) + .digest("hex"); + return sig; +}; \ No newline at end of file