diff --git a/apps/web/knip.json b/apps/web/knip.json new file mode 100644 index 000000000..30c0868f4 --- /dev/null +++ b/apps/web/knip.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://unpkg.com/knip@5/schema.json", + "ignore": ["src/components/ui/**"] +} diff --git a/apps/web/package.json b/apps/web/package.json index c7e9b70a0..b2efc1285 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -9,22 +9,17 @@ "lint": "next lint", "test": "jest", "test:watch": "jest --watch", - "postinstall": "prisma generate" + "postinstall": "prisma generate", + "knip": "knip" }, "engines": { "node": "20.x" }, "dependencies": { - "@dnd-kit/core": "^6.3.1", - "@dnd-kit/modifiers": "^9.0.0", - "@dnd-kit/sortable": "^10.0.0", - "@dnd-kit/utilities": "^3.2.2", "@headlessui/react": "^1.7.17", "@hookform/resolvers": "^5.0.1", - "@nextui-org/react": "^2.1.13", "@prisma/client": "^5.14.0", "@radix-ui/react-avatar": "^1.1.6", - "@radix-ui/react-checkbox": "^1.2.3", "@radix-ui/react-collapsible": "^1.1.8", "@radix-ui/react-dialog": "^1.1.11", "@radix-ui/react-dropdown-menu": "^2.1.11", @@ -34,21 +29,12 @@ "@radix-ui/react-select": "^2.2.2", "@radix-ui/react-separator": "^1.1.4", "@radix-ui/react-slot": "^1.2.0", - "@radix-ui/react-switch": "^1.2.2", "@radix-ui/react-tabs": "^1.1.8", - "@radix-ui/react-toggle": "^1.1.6", - "@radix-ui/react-toggle-group": "^1.1.7", - "@radix-ui/react-tooltip": "^1.2.4", - "@react-google-maps/api": "^2.19.2", - "@react-pdf/renderer": "^3.1.14", "@sendgrid/mail": "^8.1.5", "@stripe/react-stripe-js": "^2.4.0", "@stripe/stripe-js": "^2.2.0", "@tanstack/react-query": "^5.8.4", "@tanstack/react-table": "^8.21.3", - "@types/node": "20.6.0", - "@types/react": "18.2.21", - "@types/react-dom": "18.2.7", "@vercel/analytics": "^1.1.1", "@vercel/node": "^5.1.14", "@vercel/toolbar": "^0.1.34", @@ -67,48 +53,37 @@ "eslint": "8.49.0", "firebase": "^11.6.0", "firebase-admin": "^13.3.0", - "firebase-tools": "^13.11.2", "flags": "^3.1.1", - "framer-motion": "^10.16.4", - "google-map-react": "^2.2.1", "js-cookie": "^3.0.5", "jsonwebtoken": "^8.5.1", "jspdf": "^2.5.1", "lucide-react": "^0.503.0", "micro": "^10.0.1", "next": "^14.2.23", - "next-themes": "^0.4.6", "postcss": "8.4.29", "react": "18", "react-chartjs-2": "^5.2.0", "react-csv": "^2.2.2", "react-day-picker": "8.10.1", - "react-dom": "18", "react-error-boundary": "^4.0.11", "react-google-autocomplete": "^2.7.3", - "react-google-maps": "^9.4.5", "react-hook-form": "^7.55.0", "react-icons": "^4.11.0", - "react-pdf": "^7.5.1", - "react-router-dom": "^6.17.0", "recharts": "^2.15.3", "short-unique-id": "^5.0.3", "sonner": "^2.0.3", "stripe": "^14.5.0", - "swr": "^2.2.2", "tailwind-merge": "^3.2.0", "tailwindcss": "3.3.3", "tailwindcss-animate": "^1.0.7", - "troptix-api": "*", - "troptix-models": "*", - "typescript": "5.2.2", - "vaul": "^1.1.2", "zod": "^3.24.3" }, "devDependencies": { - "@testing-library/react": "^14.2.0", "@types/jest": "^29.5.12", + "@types/node": "^22.15.3", "eslint-config-next": "^14.2.23", - "prisma": "^5.14.0" + "knip": "^5.50.5", + "typescript": "^5.8.3", + "@types/react": "18.2.21" } } diff --git a/apps/web/src/app/organizer/events/[eventId]/_lib/getEventData.ts b/apps/web/src/app/organizer/events/[eventId]/_lib/getEventData.ts index 057c4aed7..64a4212a2 100644 --- a/apps/web/src/app/organizer/events/[eventId]/_lib/getEventData.ts +++ b/apps/web/src/app/organizer/events/[eventId]/_lib/getEventData.ts @@ -2,25 +2,25 @@ import { OrderStatus, Prisma } from '@prisma/client'; import { notFound } from 'next/navigation'; import prisma from '@/server/prisma'; -export type TicketTypeBreakdown = { +type TicketTypeBreakdown = { name: string; sold: number; fill: string; }; -export type DailyPerformanceDataPoint = { +type DailyPerformanceDataPoint = { date: string; revenue: number; }; -export type AttendeeSample = { +type AttendeeSample = { id: string; name: string; ticketType: string; checkedIn: boolean; // Not supported yet, could use the ticket statusfield in tickets table }; -export type OrderSample = { +type OrderSample = { id: string; customerDisplay: string; amount: number; @@ -28,7 +28,7 @@ export type OrderSample = { status: OrderStatus; }; -export type EventOverviewData = { +type EventOverviewData = { eventId: string; eventName: string; isDraft: boolean; diff --git a/apps/web/src/app/organizer/events/[eventId]/tickets/_components/TicketTable.tsx b/apps/web/src/app/organizer/events/[eventId]/tickets/_components/TicketTable.tsx index 98ec9f6cf..18ea67cee 100644 --- a/apps/web/src/app/organizer/events/[eventId]/tickets/_components/TicketTable.tsx +++ b/apps/web/src/app/organizer/events/[eventId]/tickets/_components/TicketTable.tsx @@ -42,7 +42,7 @@ const priceFilterFn: FilterFn = (row, columnId, filterValue) => { return true; }; -export const columns: ColumnDef[] = [ +const columns: ColumnDef[] = [ { accessorKey: 'name', header: 'Name', diff --git a/apps/web/src/components/AdminLayout.tsx b/apps/web/src/components/AdminLayout.tsx index 067e09a44..3237ef56b 100644 --- a/apps/web/src/components/AdminLayout.tsx +++ b/apps/web/src/components/AdminLayout.tsx @@ -1,11 +1,10 @@ -import { Menu } from 'lucide-react'; +import { Menu, ChevronDown } from 'lucide-react'; import Link from 'next/link'; import { TropTixContext } from '@/components/AuthProvider'; import AdminSidebar from '@/components/pages/admin/navigation/AdminSidebar'; import AdminSidebarMobile from '@/components/pages/admin/navigation/AdminSidebarMobile'; import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet'; -import { DownOutlined } from '@ant-design/icons'; import { Button, Dropdown, MenuProps } from 'antd'; import { useContext } from 'react'; import Logo from './ui/logo'; @@ -77,7 +76,7 @@ export default function AdminLayout({
{user.email}
- +
diff --git a/apps/web/src/components/AuthProvider.tsx b/apps/web/src/components/AuthProvider.tsx index 03113af00..91afd27b9 100644 --- a/apps/web/src/components/AuthProvider.tsx +++ b/apps/web/src/components/AuthProvider.tsx @@ -2,8 +2,6 @@ import { User, initializeUser } from '@/hooks/types/User'; import { cn } from '@/lib/utils'; -import { LoadingOutlined } from '@ant-design/icons'; -import { Spin } from 'antd'; import { onIdTokenChanged } from 'firebase/auth'; import { Inter } from 'next/font/google'; @@ -12,7 +10,7 @@ import { createContext, useContext, useEffect, useState } from 'react'; import { auth } from '../config'; import Cookies from 'js-cookie'; import { useOrganizerStatus } from '@/hooks/useUser'; - +import LoadingIndicator from '@/components/ui/loading-indicator'; const inter = Inter({ subsets: ['latin'], variable: '--font-inter', @@ -29,7 +27,7 @@ export const TropTixContext = createContext({ loading: true, }); -export const useTropTixContext = () => useContext(TropTixContext); +const useTropTixContext = () => useContext(TropTixContext); export default function AuthProvider({ children, @@ -93,9 +91,10 @@ export default function AuthProvider({ > {loading && (pathname === '/' || pathname === '/home') ? ( <> - } + ) : ( diff --git a/apps/web/src/components/TicketDetail.tsx b/apps/web/src/components/TicketDetail.tsx deleted file mode 100644 index 8fda663d6..000000000 --- a/apps/web/src/components/TicketDetail.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react'; -interface TicketTypeProps { - ticketName: string; - price: string; - description: string; - onAdd: () => void; -} -export function TicketDetail({ - ticketName, - price, - description, - onAdd, -}: TicketTypeProps) { - return ( -
-
-
-

{ticketName}

-

{price}

-
-

{description}

-
- -
- ); -} diff --git a/apps/web/src/components/navbar.tsx b/apps/web/src/components/navbar.tsx deleted file mode 100644 index fef4e0bcc..000000000 --- a/apps/web/src/components/navbar.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import Link from 'next/link'; -import { Button } from './ui/button'; - -import React, { useState } from 'react'; - -const Navbar = () => { - const [mobileMenuOpen, setMobileMenuOpen] = useState(false); - const links = [ - { name: 'Login', href: '#' }, - { name: 'Explore Events', href: '/' }, - { name: 'Contact', href: '#' }, - { name: 'Admin', href: '/admin' }, - ]; - - const toggleMobileMenu = () => { - setMobileMenuOpen(!mobileMenuOpen); - }; - return ( -
-
- -
    - {links.map((link, index) => { - return ( -
  • - - {link.name} - -
  • - ); - })} -
-
-
- ); -}; - -export default Navbar; diff --git a/apps/web/src/components/pages/admin/Sidebar.tsx b/apps/web/src/components/pages/admin/Sidebar.tsx deleted file mode 100644 index 519fbc03b..000000000 --- a/apps/web/src/components/pages/admin/Sidebar.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import Link from 'next/link'; -import { useRouter } from 'next/router'; - -export default function Sidebar({ show, setter }) { - const router = useRouter(); - - // Define our base class - const className = - 'bg-black w-[250px] transition-[margin-left] ease-in-out duration-500 fixed md:static top-0 bottom-0 left-0 z-40'; - // Append class based on state of sidebar visiblity - const appendClass = show ? ' ml-0' : ' ml-[-250px] md:ml-0'; - - // Clickable menu items - const MenuItem = ({ name, route }) => { - // Highlight menu item based on currently displayed route - const colorClass = - router.pathname === route - ? 'text-white' - : 'text-white/50 hover:text-white'; - - return ( - { - setter((oldVal) => !oldVal); - }} - className={`flex gap-1 [&>*]:my-auto text-md pl-6 py-3 border-b-[1px] border-b-white/10 ${colorClass}`} - > -
- {/* {icon} */} -
-
{name}
- - ); - }; - - // Overlay to prevent clicks in background, also serves as our close button - const ModalOverlay = () => ( -
{ - setter((oldVal) => !oldVal); - }} - /> - ); - - return ( - <> -
-
- - {/*eslint-disable-next-line*/} - {/* Company Logo */} - -
-
- - - - - -
-
- {show ? : <>} - - ); -} diff --git a/apps/web/src/components/pages/admin/manage-event/details.tsx b/apps/web/src/components/pages/admin/manage-event/details.tsx index 9e96e7145..687e8c185 100644 --- a/apps/web/src/components/pages/admin/manage-event/details.tsx +++ b/apps/web/src/components/pages/admin/manage-event/details.tsx @@ -1,11 +1,12 @@ import { CustomTextArea } from '@/components/ui/input'; import { uploadFlyerToFirebase } from '@/firebase/storage'; -import { UploadOutlined } from '@ant-design/icons'; +import { Upload as UploadIcon } from 'lucide-react'; import type { UploadProps } from 'antd'; -import { Button, Form, Image, Upload, message } from 'antd'; +import { Form, Image, Upload, message } from 'antd'; import { RcFile } from 'antd/es/upload'; import { getDownloadURL } from 'firebase/storage'; import React from 'react'; +import { Button } from '@/components/ui/button'; export default function DetailsPage({ event, setEvent, updateEvent }) { const fileUploadUrl = '/api/fileupload'; @@ -106,7 +107,8 @@ export default function DetailsPage({ event, setEvent, updateEvent }) { <> )} - @@ -152,7 +154,7 @@ export default function DetailsPage({ event, setEvent, updateEvent }) { onClick={() => { updateEvent(event); }} - type="primary" + type="button" className="px-6 py-5 shadow-md items-center bg-blue-600 hover:bg-blue-700 justify-center font-medium inline-flex" > Save Event Details diff --git a/apps/web/src/components/pages/admin/manage-event/quantity-chart.tsx b/apps/web/src/components/pages/admin/manage-event/quantity-chart.tsx index 4e8db75c3..c55c44541 100644 --- a/apps/web/src/components/pages/admin/manage-event/quantity-chart.tsx +++ b/apps/web/src/components/pages/admin/manage-event/quantity-chart.tsx @@ -20,7 +20,7 @@ ChartJS.register( Legend ); -export const options = { +const options = { responsive: true, plugins: { legend: { diff --git a/apps/web/src/components/pages/admin/manage-event/sales-chart.tsx b/apps/web/src/components/pages/admin/manage-event/sales-chart.tsx index f1d93e387..2900d0d0a 100644 --- a/apps/web/src/components/pages/admin/manage-event/sales-chart.tsx +++ b/apps/web/src/components/pages/admin/manage-event/sales-chart.tsx @@ -22,7 +22,7 @@ ChartJS.register( Legend ); -export const options = { +const options = { responsive: true, plugins: { legend: { diff --git a/apps/web/src/components/pages/event/billing-form.tsx b/apps/web/src/components/pages/event/billing-form.tsx deleted file mode 100644 index f70cdd673..000000000 --- a/apps/web/src/components/pages/event/billing-form.tsx +++ /dev/null @@ -1,160 +0,0 @@ -import { Form, message } from 'antd'; - -import { CustomInput } from '@/components/ui/input'; -import { loadStripe } from '@stripe/stripe-js'; -const stripeKey = process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY; -const stripePromise = loadStripe(stripeKey ? stripeKey : ''); - -export default function BillingForm({ checkout, setCheckout }) { - const [messageApi, contextHolder] = message.useMessage(); - - function handleChange(event: React.ChangeEvent) { - setCheckout((prevState) => ({ - ...prevState, - [event.target.name]: event.target.value, - })); - } - - const onFinishFailed = (errorInfo: any) => {}; - - const onFinish = (values: any) => {}; - - return ( -
- {contextHolder} -
-
-

- Contact Information -

- -
-
- -
-
- -
-
-
-
- -
-
- -

- Billing Address -

- -
-
- -
-
-
-
- -
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-
-
- ); -} diff --git a/apps/web/src/components/pages/event/ticket-drawer.tsx b/apps/web/src/components/pages/event/ticket-drawer.tsx index 534197428..161c62a68 100644 --- a/apps/web/src/components/pages/event/ticket-drawer.tsx +++ b/apps/web/src/components/pages/event/ticket-drawer.tsx @@ -1,6 +1,6 @@ import { Button } from '@/components/ui/button'; import { getFormattedCurrency } from '@/lib/utils'; -import { ShoppingCartOutlined } from '@ant-design/icons'; +import { ShoppingCart } from 'lucide-react'; import { Drawer, List, Steps } from 'antd'; import { useState } from 'react'; import { CheckoutContainer } from './CheckoutContainer'; @@ -109,7 +109,7 @@ export default function TicketDrawer({ event, isTicketModalOpen, onClose }) {
{checkout.tickets.size === 0 ? (
- +
Cart is empty
) : ( diff --git a/apps/web/src/components/pages/event/ticket-modal.tsx b/apps/web/src/components/pages/event/ticket-modal.tsx index e2f5ea91e..f1034ac19 100644 --- a/apps/web/src/components/pages/event/ticket-modal.tsx +++ b/apps/web/src/components/pages/event/ticket-modal.tsx @@ -6,7 +6,7 @@ import { DialogTitle, } from '@/components/ui/dialog'; import { getFormattedCurrency } from '@/lib/utils'; -import { ShoppingCartOutlined } from '@ant-design/icons'; +import { ShoppingCart } from 'lucide-react'; import { List, Steps } from 'antd'; import Image from 'next/image'; import { CheckoutContainer } from './CheckoutContainer'; @@ -101,7 +101,7 @@ export default function TicketModal({ event, isTicketModalOpen, onClose }) {
{Object.keys(checkout?.tickets).length === 0 ? (
- +
Cart is empty
) : ( diff --git a/apps/web/src/components/pages/event/tickets-checkout-forms.tsx b/apps/web/src/components/pages/event/tickets-checkout-forms.tsx index fbf9a542d..da59e19d2 100644 --- a/apps/web/src/components/pages/event/tickets-checkout-forms.tsx +++ b/apps/web/src/components/pages/event/tickets-checkout-forms.tsx @@ -11,12 +11,12 @@ import { } from '@/components/ui/form'; import { TropTixContext } from '@/components/AuthProvider'; -import { Button, ButtonWithIcon } from '@/components/ui/button'; +import { Button } from '@/components/ui/button'; import { InputWithLabel } from '@/components/ui/input'; import { TypographyH3 } from '@/components/ui/typography'; import { CheckoutTicket } from '@/types/checkout'; import { getDateFormatter } from '@/lib/dateUtils'; -import { MinusOutlined, PlusOutlined } from '@ant-design/icons'; +import { Minus, Plus } from 'lucide-react'; import { UseFormReturn } from 'react-hook-form'; import { UserDetailsFormData } from '@/lib/schemas/checkoutSchema'; import { Input } from '@/components/ui/input'; @@ -210,7 +210,7 @@ export default function TicketsCheckoutForm({
{ticket.name}
-
+
{ticketState !== undefined ? (
@@ -218,32 +218,33 @@ export default function TicketsCheckoutForm({
) : (
- updateCost(ticket, true)} - className="bg-blue-500 rounded h-8 w-8" - size={'sm'} + className="rounded !h-8 !w-8 flex-shrink-0" disabled={ checkout.tickets[ticket.id] === 0 || checkout.tickets[ticket.id] === undefined } - icon={ - - } - > + > + + + +
{checkout.tickets[ticket.id] ?? 0}
- updateCost(ticket, false)} - className="bg-blue-500 rounded h-8 w-8" + className="rounded !h-8 !w-8 flex-shrink-0" disabled={ checkout.tickets[ticket.id] === maxAllowedToAdd } - icon={ - - } - > + > + + + +
)}
diff --git a/apps/web/src/components/pages/home/current-events.tsx b/apps/web/src/components/pages/home/current-events.tsx deleted file mode 100644 index a85203604..000000000 --- a/apps/web/src/components/pages/home/current-events.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import Link from 'next/link'; - -export default function CurrentEvents() { - return ( -
- {/* Section background (needs .relative class on parent and next sibling elements) */} - -
-
- -
-
- {/* Section header */} -
-

Explore our current events

-

- Duis aute irure dolor in reprehenderit in voluptate velit esse - cillum dolore eu fugiat nulla pariatur excepteur sint occaecat - cupidatat. -

-
- - Explore Events - -
-
-
-
-
- ); -} diff --git a/apps/web/src/components/pages/home/newsletter.tsx b/apps/web/src/components/pages/home/newsletter.tsx deleted file mode 100644 index fc59c512f..000000000 --- a/apps/web/src/components/pages/home/newsletter.tsx +++ /dev/null @@ -1,133 +0,0 @@ -export default function Newsletter() { - return ( -
-
-
- {/* CTA box */} -
- {/* Background illustration */} - - -
- {/* CTA content */} -
-

- Want to host events on our platform? -

-

- Get in touch with our team today and see how we can improve - your event management needs. -

- - {/* CTA form */} -
- - {/* Success message */} - {/*

Thanks for subscribing!

*/} - {/*

No spam. You can unsubscribe at any time.

*/} -
-
-
-
-
-
-
- ); -} diff --git a/apps/web/src/components/pages/home/testimonials.tsx b/apps/web/src/components/pages/home/testimonials.tsx index ae0f91c59..bf1c72806 100644 --- a/apps/web/src/components/pages/home/testimonials.tsx +++ b/apps/web/src/components/pages/home/testimonials.tsx @@ -1,8 +1,8 @@ import { CustomInput, CustomTextArea } from '@/components/ui/input'; import { ContactUsForm } from '@/hooks/types/Contact'; import { PostContactRequest, useCreateContact } from '@/hooks/usePostContact'; -import { SmileOutlined } from '@ant-design/icons'; import { Button, Result, message } from 'antd'; +import { Smile } from 'lucide-react'; import Image from 'next/image'; import { useState } from 'react'; @@ -146,9 +146,13 @@ export default function Testimonials() {
- {isFormSubmitted ? ( + {true ? ( } + icon={ + + + + } title="Submitted, thank you for your message!" /> ) : ( diff --git a/apps/web/src/components/ui/admin-header.tsx b/apps/web/src/components/ui/admin-header.tsx deleted file mode 100644 index 96292fcaa..000000000 --- a/apps/web/src/components/ui/admin-header.tsx +++ /dev/null @@ -1,223 +0,0 @@ -'use client'; - -import { useContext, useEffect, useState } from 'react'; - -import { Disclosure } from '@headlessui/react'; -import { Dropdown, MenuProps } from 'antd'; -import Image from 'next/image'; -import Link from 'next/link'; -import { useRouter } from 'next/router'; -import { GiHamburgerMenu } from 'react-icons/gi'; - -import { - MdAdd, - MdOutlineEvent, - MdOutlineLogout, - MdOutlineMoreHoriz, - MdOutlineSettings, -} from 'react-icons/md'; - -import { usePathname } from 'next/navigation'; -import { AiOutlineHome } from 'react-icons/ai'; -import { auth } from '../../config'; -import { TropTixContext } from '../AuthProvider'; -import AdminMobileMenu from './admin-mobile-menu'; - -export default function AdminHeader() { - const { user } = useContext(TropTixContext); - const pathname = usePathname(); - const [top, setTop] = useState(true); - - // detect whether user has scrolled the page down by 10px - const scrollHandler = () => { - window.pageYOffset > 10 ? setTop(false) : setTop(true); - }; - - const router = useRouter(); - - useEffect(() => { - scrollHandler(); - window.addEventListener('scroll', scrollHandler); - return () => window.removeEventListener('scroll', scrollHandler); - }, [top]); - - async function signOut() { - await auth.signOut(); - router.push('/'); - } - - const items: MenuProps['items'] = [ - { - key: '1', - label: ( - - Home - - ), - }, - { - key: '2', - label: ( - - Sign Out - - ), - }, - ]; - - function oldNavBar() { - return ( -
- -
- ); - } - - return ( -
-
-
-
- - troptix-logo - -
- -
- -
- - {!user ? ( - <> - ) : ( -
- -
- )} - - -
-
-
- ); -} diff --git a/apps/web/src/components/ui/admin-mobile-menu.tsx b/apps/web/src/components/ui/admin-mobile-menu.tsx deleted file mode 100644 index 2d2eda8c0..000000000 --- a/apps/web/src/components/ui/admin-mobile-menu.tsx +++ /dev/null @@ -1,154 +0,0 @@ -'use client'; - -import { Transition } from '@headlessui/react'; -import { Dropdown, MenuProps } from 'antd'; -import Link from 'next/link'; -import { useRouter } from 'next/router'; -import { useContext, useEffect, useRef, useState } from 'react'; -import { auth } from '../../config'; -import { TropTixContext } from '../AuthProvider'; - -export default function AdminMobileMenu() { - const { user } = useContext(TropTixContext); - const [mobileNavOpen, setMobileNavOpen] = useState(false); - const router = useRouter(); - - const trigger = useRef(null); - const mobileNav = useRef(null); - - // close the mobile menu on click outside - useEffect(() => { - const clickHandler = ({ target }: { target: EventTarget | null }): void => { - if (!mobileNav.current || !trigger.current) return; - if ( - !mobileNavOpen || - mobileNav.current.contains(target as Node) || - trigger.current.contains(target as Node) - ) - return; - setMobileNavOpen(false); - }; - document.addEventListener('click', clickHandler); - return () => document.removeEventListener('click', clickHandler); - }); - - // close the mobile menu if the esc key is pressed - useEffect(() => { - const keyHandler = ({ keyCode }: { keyCode: number }): void => { - if (!mobileNavOpen || keyCode !== 27) return; - setMobileNavOpen(false); - }; - document.addEventListener('keydown', keyHandler); - return () => document.removeEventListener('keydown', keyHandler); - }); - - function closeMobileMenu() { - setMobileNavOpen(false); - } - - async function signOut() { - await auth.signOut(); - router.push('/'); - } - - const items: MenuProps['items'] = [ - { - key: '1', - label: ( - - Home - - ), - }, - { - key: '2', - label: ( - - Sign Out - - ), - }, - ]; - - return ( -
- {/* Hamburger button */} - - - {/*Mobile navigation */} -
- -
    -
  • - - {' '} - Account - -
  • -
  • - - Manage Events - -
  • -
  • - - Add Event - -
  • - {!user ? ( - <> - ) : ( -
  • - - -
    {user.email}
    -
    -
    -
  • - )} -
-
-
-
- ); -} diff --git a/apps/web/src/components/ui/checkbox.tsx b/apps/web/src/components/ui/checkbox.tsx deleted file mode 100644 index c6fdd071b..000000000 --- a/apps/web/src/components/ui/checkbox.tsx +++ /dev/null @@ -1,30 +0,0 @@ -"use client" - -import * as React from "react" -import * as CheckboxPrimitive from "@radix-ui/react-checkbox" -import { Check } from "lucide-react" - -import { cn } from "@/lib/utils" - -const Checkbox = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - - - -)) -Checkbox.displayName = CheckboxPrimitive.Root.displayName - -export { Checkbox } diff --git a/apps/web/src/components/ui/drawer.tsx b/apps/web/src/components/ui/drawer.tsx deleted file mode 100644 index ca5fbd5b0..000000000 --- a/apps/web/src/components/ui/drawer.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import * as React from 'react'; -import { Drawer as DrawerPrimitive } from 'vaul'; - -import { cn } from '@/lib/utils'; - -const Drawer = ({ - shouldScaleBackground = true, - ...props -}: React.ComponentProps) => ( - -); -Drawer.displayName = 'Drawer'; - -const DrawerTrigger = DrawerPrimitive.Trigger; - -const DrawerPortal = DrawerPrimitive.Portal; - -const DrawerClose = DrawerPrimitive.Close; - -const DrawerOverlay = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName; - -const DrawerContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - - - - {/*
*/} - {children} - - -)); -DrawerContent.displayName = 'DrawerContent'; - -const DrawerHeader = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-); -DrawerHeader.displayName = 'DrawerHeader'; - -const DrawerFooter = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-); -DrawerFooter.displayName = 'DrawerFooter'; - -const DrawerTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DrawerTitle.displayName = DrawerPrimitive.Title.displayName; - -const DrawerDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DrawerDescription.displayName = DrawerPrimitive.Description.displayName; - -export { - Drawer, - DrawerClose, - DrawerContent, - DrawerDescription, - DrawerFooter, - DrawerHeader, - DrawerOverlay, - DrawerPortal, - DrawerTitle, - DrawerTrigger, -}; diff --git a/apps/web/src/components/ui/header.tsx b/apps/web/src/components/ui/header.tsx index 0fb964a36..8c0c0243f 100644 --- a/apps/web/src/components/ui/header.tsx +++ b/apps/web/src/components/ui/header.tsx @@ -2,7 +2,6 @@ import { useContext, useEffect, useState } from 'react'; -import { DownOutlined } from '@ant-design/icons'; import { Button, Dropdown, MenuProps } from 'antd'; import Image from 'next/image'; import Link from 'next/link'; @@ -11,6 +10,7 @@ import React from 'react'; import { auth } from '../../config'; import { TropTixContext } from '../AuthProvider'; import MobileMenu from './mobile-menu'; +import { ChevronDown } from 'lucide-react'; export default function Header() { const [top, setTop] = useState(true); @@ -151,7 +151,7 @@ export default function Header() {
{user.email}
- +
diff --git a/apps/web/src/components/ui/icon.tsx b/apps/web/src/components/ui/icon.tsx deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/web/src/components/ui/loading-indicator.tsx b/apps/web/src/components/ui/loading-indicator.tsx new file mode 100644 index 000000000..02add2079 --- /dev/null +++ b/apps/web/src/components/ui/loading-indicator.tsx @@ -0,0 +1,42 @@ +import React from 'react'; + +/** + * LoadingIndicator Component + * + * A simple, reusable loading indicator using Tailwind CSS for styling. + * It displays a spinning circle animation. + * + * Props: + * - className (string, optional): Additional CSS classes to apply to the container div. + * - size (string, optional): Tailwind width/height class (e.g., 'w-8 h-8', 'w-12 h-12'). Defaults to 'w-8 h-8'. + * - color (string, optional): Tailwind border color class for the spinner (e.g., 'border-blue-500'). Defaults to 'border-blue-500'. + * - text (string, optional): Optional text to display below the spinner (e.g., "Loading..."). + * - textClassName (string, optional): Additional CSS classes for the text element. + */ +const LoadingIndicator = ({ + className = '', + size = 'w-8 h-8', // Default size + thickness = 'border-4', // Default thickness + color = 'border-blue-500', // Default color + text = '', + textClassName = 'mt-2 text-sm text-gray-600', // Default text style +}) => { + // Combine default and provided classes + const containerClasses = `flex flex-col items-center justify-center ${className}`; + const spinnerClasses = `animate-spin rounded-full ${thickness} border-t-transparent ${size} ${color}`; + const textClasses = `${textClassName}`; + + return ( +
+ {/* The spinning element */} +
+ {/* Screen reader accessible text */} + Loading... +
+ {/* Optional text below the spinner */} + {text &&

{text}

} +
+ ); +}; + +export default LoadingIndicator; diff --git a/apps/web/src/components/ui/loading-spinner.tsx b/apps/web/src/components/ui/loading-spinner.tsx deleted file mode 100644 index 4b28c1c8b..000000000 --- a/apps/web/src/components/ui/loading-spinner.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { Spin } from 'antd'; - -export function LoadingSpinner({ children }) { - return ( - -
- - ); -} diff --git a/apps/web/src/components/ui/message.tsx b/apps/web/src/components/ui/message.tsx deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/web/src/components/ui/mobile-menu.tsx b/apps/web/src/components/ui/mobile-menu.tsx index 893257ae0..260a6e8bd 100644 --- a/apps/web/src/components/ui/mobile-menu.tsx +++ b/apps/web/src/components/ui/mobile-menu.tsx @@ -1,6 +1,5 @@ 'use client'; -import { DownOutlined } from '@ant-design/icons'; import { Transition } from '@headlessui/react'; import { Dropdown, MenuProps } from 'antd'; import Link from 'next/link'; @@ -8,7 +7,7 @@ import { usePathname } from 'next/navigation'; import { useContext, useEffect, useRef, useState } from 'react'; import { auth } from '../../config'; import { TropTixContext } from '../AuthProvider'; - +import { ChevronDown } from 'lucide-react'; export default function MobileMenu() { const [mobileNavOpen, setMobileNavOpen] = useState(false); const { user } = useContext(TropTixContext); @@ -201,7 +200,7 @@ export default function MobileMenu() {
{user.email}
- +
diff --git a/apps/web/src/components/ui/skeleton.tsx b/apps/web/src/components/ui/skeleton.tsx deleted file mode 100644 index d7e45f7bd..000000000 --- a/apps/web/src/components/ui/skeleton.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { cn } from "@/lib/utils" - -function Skeleton({ - className, - ...props -}: React.HTMLAttributes) { - return ( -
- ) -} - -export { Skeleton } diff --git a/apps/web/src/components/ui/spinner.tsx b/apps/web/src/components/ui/spinner.tsx index df32d6ae4..115378ab0 100644 --- a/apps/web/src/components/ui/spinner.tsx +++ b/apps/web/src/components/ui/spinner.tsx @@ -1,13 +1,9 @@ -import { LoadingOutlined } from '@ant-design/icons'; -import { Spin } from 'antd'; - +import LoadingIndicator from '@/components/ui/loading-indicator'; +// TODO: Merge with LoadingIndicator component export function Spinner({ text }) { return (
- } - /> +
{text}
); diff --git a/apps/web/src/components/ui/switch.tsx b/apps/web/src/components/ui/switch.tsx deleted file mode 100644 index 5f4117f0f..000000000 --- a/apps/web/src/components/ui/switch.tsx +++ /dev/null @@ -1,29 +0,0 @@ -"use client" - -import * as React from "react" -import * as SwitchPrimitives from "@radix-ui/react-switch" - -import { cn } from "@/lib/utils" - -const Switch = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - -)) -Switch.displayName = SwitchPrimitives.Root.displayName - -export { Switch } diff --git a/apps/web/src/components/ui/toggle.tsx b/apps/web/src/components/ui/toggle.tsx deleted file mode 100644 index c19bea373..000000000 --- a/apps/web/src/components/ui/toggle.tsx +++ /dev/null @@ -1,45 +0,0 @@ -"use client" - -import * as React from "react" -import * as TogglePrimitive from "@radix-ui/react-toggle" -import { cva, type VariantProps } from "class-variance-authority" - -import { cn } from "@/lib/utils" - -const toggleVariants = cva( - "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 gap-2", - { - variants: { - variant: { - default: "bg-transparent", - outline: - "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground", - }, - size: { - default: "h-10 px-3 min-w-10", - sm: "h-9 px-2.5 min-w-9", - lg: "h-11 px-5 min-w-11", - }, - }, - defaultVariants: { - variant: "default", - size: "default", - }, - } -) - -const Toggle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & - VariantProps ->(({ className, variant, size, ...props }, ref) => ( - -)) - -Toggle.displayName = TogglePrimitive.Root.displayName - -export { Toggle, toggleVariants } diff --git a/apps/web/src/components/ui/tooltip.tsx b/apps/web/src/components/ui/tooltip.tsx deleted file mode 100644 index 60d9678cf..000000000 --- a/apps/web/src/components/ui/tooltip.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from "react" -import * as TooltipPrimitive from "@radix-ui/react-tooltip" - -import { cn } from "@/lib/utils" - -const TooltipProvider = TooltipPrimitive.Provider - -const Tooltip = TooltipPrimitive.Root - -const TooltipTrigger = TooltipPrimitive.Trigger - -const TooltipContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, sideOffset = 4, ...props }, ref) => ( - -)) -TooltipContent.displayName = TooltipPrimitive.Content.displayName - -export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } diff --git a/apps/web/src/components/utils/dropdown.tsx b/apps/web/src/components/utils/dropdown.tsx deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/web/src/config.js b/apps/web/src/config.js index 400c8e918..b8c5ac868 100644 --- a/apps/web/src/config.js +++ b/apps/web/src/config.js @@ -15,6 +15,6 @@ const firebaseConfig = { let firebaseApp = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0]; -export const app = firebaseApp; +const app = firebaseApp; export const auth = getAuth(firebaseApp); export const storage = getStorage(firebaseApp); diff --git a/apps/web/src/firebase/remoteConfig.ts b/apps/web/src/firebase/remoteConfig.ts deleted file mode 100644 index 0732ddba4..000000000 --- a/apps/web/src/firebase/remoteConfig.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const TROPTIX_FEE_FLAT = 'TROPTIX_FEE_FLAT'; -export const TROPTIX_FEE_PERCENTAGE = 'TROPTIX_FEE_PERCENTAGE'; -export const TROPTIX_FEE_TAX = 'TROPTIX_FEE_TAX'; -export const TROPTIX_ORGANIZER_ALLOW_LIST = 'TROPTIX_ORGANIZER_ALLOW_LIST'; diff --git a/apps/web/src/hooks/types/Charge.tsx b/apps/web/src/hooks/types/Charge.tsx deleted file mode 100644 index 631ee28e9..000000000 --- a/apps/web/src/hooks/types/Charge.tsx +++ /dev/null @@ -1,4 +0,0 @@ -export type Charge = { - total: number; - userId: string; -}; diff --git a/apps/web/src/hooks/types/Checkout.ts b/apps/web/src/hooks/types/Checkout.ts index 635312ee1..5991a64a5 100644 --- a/apps/web/src/hooks/types/Checkout.ts +++ b/apps/web/src/hooks/types/Checkout.ts @@ -22,7 +22,7 @@ export interface Checkout { tickets: Map; } -export function initializeCheckout(user: any, eventId: string): Checkout { +function initializeCheckout(user: any, eventId: string): Checkout { const checkout: Checkout = { id: '', eventId: eventId, @@ -57,7 +57,7 @@ export interface CheckoutTicket { ticketType: TicketsType; } -export function initializeCheckoutTicket(ticket): CheckoutTicket { +function initializeCheckoutTicket(ticket): CheckoutTicket { const checkoutTicket: CheckoutTicket = { id: '', ticketTypeId: ticket.id, diff --git a/apps/web/src/hooks/types/Order.ts b/apps/web/src/hooks/types/Order.ts index aea7f28f8..bb9eb705a 100644 --- a/apps/web/src/hooks/types/Order.ts +++ b/apps/web/src/hooks/types/Order.ts @@ -9,9 +9,7 @@ type Ticket = { export enum OrderStatus { PENDING = 'PENDING', - CANCELLED = 'CANCELLED', - COMPLETED = 'COMPLETED', -} + } export type Order = { id?: string; diff --git a/apps/web/src/hooks/types/User.tsx b/apps/web/src/hooks/types/User.tsx index 6d7790509..1a9b15044 100644 --- a/apps/web/src/hooks/types/User.tsx +++ b/apps/web/src/hooks/types/User.tsx @@ -26,7 +26,7 @@ enum Role { ORGANIZER, } -export enum SocialMediaAccounts { +enum SocialMediaAccounts { FACEBOOK = 'FACEBOOK', INSTAGRAM = 'INSTAGRAM', TIKTOK = 'TIKTOK', @@ -73,7 +73,7 @@ export async function initializeUser( return user; } -export function initializeUserWithJwtToken(token: string): User { +function initializeUserWithJwtToken(token: string): User { const user: User = { id: '', jwtToken: token, diff --git a/apps/web/src/hooks/useDelegatedUser.tsx b/apps/web/src/hooks/useDelegatedUser.tsx index c32995034..1a942da60 100644 --- a/apps/web/src/hooks/useDelegatedUser.tsx +++ b/apps/web/src/hooks/useDelegatedUser.tsx @@ -12,7 +12,7 @@ export interface DeleteDelegatedUserRequest { jwtToken?: string; } -export async function mutateDelegatedUser( +async function mutateDelegatedUser( request: PostDelegatedUserRequest ): Promise { const url = '/api/delegatedUsers'; @@ -39,7 +39,7 @@ export async function mutateDelegatedUser( }); } -export async function deleteDelegatedUser( +async function deleteDelegatedUser( request: DeleteDelegatedUserRequest ): Promise { const url = `/api/delegatedUsers?id=${request.id}`; @@ -79,7 +79,7 @@ export function useDeleteDelegatedUser() { }); } -export async function delegatedUserFetcher( +async function delegatedUserFetcher( eventId: string, jwtToken: string ): Promise { diff --git a/apps/web/src/hooks/useEvents.ts b/apps/web/src/hooks/useEvents.ts index 1638b6b7d..5ff729350 100644 --- a/apps/web/src/hooks/useEvents.ts +++ b/apps/web/src/hooks/useEvents.ts @@ -95,7 +95,7 @@ export const useUpdateEvent = () => { }; // Delete an event -export const useDeleteEvent = () => { +const useDeleteEvent = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (id: string) => { diff --git a/apps/web/src/hooks/useFetchEvents.tsx b/apps/web/src/hooks/useFetchEvents.tsx index 10a84c5c3..e2491ff11 100644 --- a/apps/web/src/hooks/useFetchEvents.tsx +++ b/apps/web/src/hooks/useFetchEvents.tsx @@ -6,16 +6,15 @@ export enum RequestType { GET_EVENTS_ALL = 'GET_EVENTS_ALL', GET_EVENTS_BY_ID = 'GET_EVENTS_BY_ID', GET_EVENTS_BY_ORGANIZER = 'GET_EVENTS_BY_ORGANIZER', - GET_EVENTS_SCANNABLE_BY_ORGANIZER = 'GET_EVENTS_SCANNABLE_BY_ORGANIZER', -} -export type GetEventsRequestType = { + } +type GetEventsRequestType = { requestType: keyof typeof RequestType; id?: string; jwtToken?: string; userId?: string; }; -export async function eventFetcher({ +async function eventFetcher({ requestType, id, jwtToken, @@ -57,7 +56,7 @@ export async function eventFetcher({ }); } -export function useFetchAllEvents(initialData?) { +function useFetchAllEvents(initialData?) { const { user } = useContext(TropTixContext); const { isPending, isError, data, error } = useQuery({ queryKey: [RequestType.GET_EVENTS_ALL], diff --git a/apps/web/src/hooks/useOrders.ts b/apps/web/src/hooks/useOrders.ts index ff91b7a59..3846205d1 100644 --- a/apps/web/src/hooks/useOrders.ts +++ b/apps/web/src/hooks/useOrders.ts @@ -14,7 +14,7 @@ export enum GetOrdersType { GET_PENDING_ORDERS_FOR_EVENT = 'GET_PENDING_ORDERS_FOR_EVENT', } -export interface GetOrdersRequest { +interface GetOrdersRequest { getOrdersType: keyof typeof GetOrdersType; id?: string; email?: string; @@ -22,7 +22,6 @@ export interface GetOrdersRequest { } export enum PostOrdersType { - POST_ORDERS_CREATE_CHARGE = 'POST_ORDERS_CREATE_CHARGE', POST_ORDERS_CREATE_ORDER = 'POST_ORDERS_CREATE_ORDER', POST_ORDERS_CREATE_COMPLEMENTARY_ORDER = 'POST_ORDERS_CREATE_COMPLEMENTARY_ORDER', POST_ORDERS_CREATE_FREE_ORDER = 'POST_ORDERS_CREATE_FREE_ORDER', @@ -83,7 +82,7 @@ export function useFetchEventOrders(eventId: string) { } // fetch the events for a specific event currently -export function useFetchPendingEventOrders(eventId: string) { +function useFetchPendingEventOrders(eventId: string) { const { user } = useContext(TropTixContext); const getOrdersType = GetOrdersType.GET_PENDING_ORDERS_FOR_EVENT; const id = eventId; @@ -95,7 +94,7 @@ export function useFetchPendingEventOrders(eventId: string) { }); } -export async function getOrders({ +async function getOrders({ getOrdersType, id, email, @@ -130,7 +129,7 @@ export async function getOrders({ } } -export function useCreateOrder() { +function useCreateOrder() { return useMutation({ mutationFn: async ({ checkout, @@ -184,7 +183,7 @@ export function useCreateComplementaryOrder() { }); } -export async function postOrders({ +async function postOrders({ type, order, charge, diff --git a/apps/web/src/hooks/usePostContact.tsx b/apps/web/src/hooks/usePostContact.tsx index bba43af2d..7b62dfb91 100644 --- a/apps/web/src/hooks/usePostContact.tsx +++ b/apps/web/src/hooks/usePostContact.tsx @@ -1,7 +1,7 @@ import { ContactUsForm } from './types/Contact'; import { useMutation } from '@tanstack/react-query'; -export enum PostContactRequestType { +enum PostContactRequestType { CONTACT_US = 'CONTACT_US', } export type PostContactRequest = { @@ -9,7 +9,7 @@ export type PostContactRequest = { contactUsForm?: ContactUsForm; }; -export async function mutateContact(request: PostContactRequest): Promise { +async function mutateContact(request: PostContactRequest): Promise { let url = `/api/contact`; try { diff --git a/apps/web/src/hooks/usePostEvent.tsx b/apps/web/src/hooks/usePostEvent.tsx index 841f2bb0c..d050b6b69 100644 --- a/apps/web/src/hooks/usePostEvent.tsx +++ b/apps/web/src/hooks/usePostEvent.tsx @@ -1,6 +1,6 @@ import { useMutation } from '@tanstack/react-query'; -export async function mutateEvent(event, editEvent): Promise { +async function mutateEvent(event, editEvent): Promise { let url = `/api/events`; let method = editEvent ? 'PUT' : 'POST'; @@ -29,7 +29,7 @@ export async function mutateEvent(event, editEvent): Promise { } } -export function useCreateEvent() { +function useCreateEvent() { return useMutation({ mutationFn: (e) => mutateEvent(e, false) }); } diff --git a/apps/web/src/hooks/usePostStripe.tsx b/apps/web/src/hooks/usePostStripe.tsx deleted file mode 100644 index 16a52c1ac..000000000 --- a/apps/web/src/hooks/usePostStripe.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { useMutation } from '@tanstack/react-query'; -import { Charge } from './types/Charge'; -import { Checkout } from './types/Checkout'; - -export enum PostStripeType { - CREATE_CHARGE = 'CREATE_CHARGE', -} - -export interface PostStripeRequest { - type: keyof typeof PostStripeType; - charge?: Charge; -} - -export interface PaymentIntent { - paymentId: string; - clientSecret: string; - ephemeralKey: string; - customerId: string; - currentTabIndex?: number; - error?: Error; -} - -export interface InitializeStripeDetailsResponse { - currentTabIndex?: number; - clientSecret?: string; - orderId?: string; -} - -export function useCreatePaymentIntent() { - return useMutation({ - mutationFn: ({ checkout }: { checkout: Checkout }) => - createPaymentIntent({ checkout }), - }); -} - -function createCharge(checkout: Checkout): Charge { - const totalPrice = checkout?.total as number; - const total = totalPrice * 100; - - const charge: Charge = { - total: Math.round(total), - userId: checkout.userId as string, - name: checkout?.firstName + ' ' + checkout?.lastName, - email: checkout.email, - }; - return charge; -} - -async function createPaymentIntent({ checkout }: { checkout: Checkout }) { - return postStripe({ - type: PostStripeType.CREATE_CHARGE, - charge: createCharge(checkout), - }); -} - -export async function postStripe({ - type, - charge, -}: PostStripeRequest): Promise { - try { - let url = `/api/stripe`; - const request = { type, charge }; - - const response = await fetch(url, { - method: 'POST', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify(request), - }); - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - - const json = await response.json(); - return json; - } catch (error) { - console.error('Error in postStripe:', error); - throw error; - } -} diff --git a/apps/web/src/hooks/usePromotions.tsx b/apps/web/src/hooks/usePromotions.tsx index cec77c278..bde92e66a 100644 --- a/apps/web/src/hooks/usePromotions.tsx +++ b/apps/web/src/hooks/usePromotions.tsx @@ -1,12 +1,12 @@ import { useMutation, useQuery } from '@tanstack/react-query'; import { Promotion } from './types/Promotion'; -export enum GetPromotionsType { +enum GetPromotionsType { GET_ALL_PROMOTIONS_FOR_EVENT = 'GET_ALL_PROMOTIONS_FOR_EVENT', GET_PROMOTIONS_BY_CODE = 'GET_PROMOTIONS_BY_CODE', } -export interface GetPromotionsRequest { +interface GetPromotionsRequest { getPromotionsType: GetPromotionsType; eventId?: string; code?: string; @@ -34,7 +34,7 @@ export function useFetchPromotionsForEvent(eventId: string) { }); } -export async function getPromotions({ +async function getPromotions({ getPromotionsType, eventId, code, @@ -76,7 +76,7 @@ export function useDeletePromotion() { }); } -export async function mutatePromotion( +async function mutatePromotion( request: PostPromotionRequest ): Promise { const url = '/api/promotions'; @@ -103,7 +103,7 @@ export async function mutatePromotion( }); } -export async function deletePromotion( +async function deletePromotion( request: DeletePromotionRequest ): Promise { const url = `/api/promotions?id=${request.id}`; diff --git a/apps/web/src/hooks/useScreenSize.test.ts b/apps/web/src/hooks/useScreenSize.test.ts deleted file mode 100644 index a24d167ca..000000000 --- a/apps/web/src/hooks/useScreenSize.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { renderHook, act } from '@testing-library/react'; -import { useScreenSize } from './useScreenSize'; - -describe('useScreenSize', () => { - const originalInnerWidth = window.innerWidth; - - afterEach(() => { - // Reset the window width after each test - window.innerWidth = originalInnerWidth; - act(() => { - window.dispatchEvent(new Event('resize')); - }); - }); - - test('should return isMobile true when width is less than 768px', () => { - window.innerWidth = 767; - const { result } = renderHook(() => useScreenSize()); - - expect(result.current.isMobile).toBe(true); - expect(result.current.width).toBe(767); - }); - - it('should return isMobile false when width is 768px or greater', () => { - window.innerWidth = 768; - const { result } = renderHook(() => useScreenSize()); - - expect(result.current.isMobile).toBe(false); - expect(result.current.width).toBe(768); - }); - - it('should update values when window is resized', () => { - const { result } = renderHook(() => useScreenSize()); - - // Initial large screen - window.innerWidth = 1024; - act(() => { - window.dispatchEvent(new Event('resize')); - }); - - expect(result.current.isMobile).toBe(false); - expect(result.current.width).toBe(1024); - - // Resize to mobile - window.innerWidth = 500; - act(() => { - window.dispatchEvent(new Event('resize')); - }); - - expect(result.current.isMobile).toBe(true); - expect(result.current.width).toBe(500); - }); -}); diff --git a/apps/web/src/hooks/useTicket.ts b/apps/web/src/hooks/useTicket.ts index 573a89314..a2ea978e8 100644 --- a/apps/web/src/hooks/useTicket.ts +++ b/apps/web/src/hooks/useTicket.ts @@ -14,7 +14,7 @@ export interface PostTicketRequest { jwtToken?: string; } -export async function mutateTicket(request: PostTicketRequest): Promise { +async function mutateTicket(request: PostTicketRequest): Promise { let url = `/api/tickets`; try { @@ -47,7 +47,7 @@ export function useCreateTicket() { }); } -export async function fetchUserTickets(userId: string): Promise { +async function fetchUserTickets(userId: string): Promise { const url = `/api/tickets?userId=${userId}`; try { @@ -69,7 +69,7 @@ export async function fetchUserTickets(userId: string): Promise { } } -export function useFetchUserTickets() { +function useFetchUserTickets() { const { user } = useContext(TropTixContext); const userId = user.id; return useQuery({ diff --git a/apps/web/src/hooks/useTicketType.tsx b/apps/web/src/hooks/useTicketType.tsx index badb44efb..f7dc0e9f1 100644 --- a/apps/web/src/hooks/useTicketType.tsx +++ b/apps/web/src/hooks/useTicketType.tsx @@ -6,18 +6,18 @@ import { Checkout } from './types/Checkout'; import { Promotion } from './types/Promotion'; import { TicketType } from './types/Ticket'; -export enum GetTicketTypesType { +enum GetTicketTypesType { GET_TICKET_TYPES_FOR_CHECKOUT = 'GET_TICKET_TYPES_FOR_CHECKOUT', GET_TICKET_TYPES_BY_EVENT = 'GET_TICKET_TYPES_BY_EVENT', } -export interface GetTicketTypeRequest { +interface GetTicketTypeRequest { getTicketTypesType: keyof typeof GetTicketTypesType; eventId?: string; jwtToken?: string; } -export interface CheckOrderValidityResponse { +interface CheckOrderValidityResponse { valid?: boolean; checkout?: Checkout; ticketTypes?: TicketType[]; @@ -35,7 +35,7 @@ export function useFetchTicketTypesByEvent(eventId: string) { }); } -export function useFetchTicketTypesForCheckout(eventId: string) { +function useFetchTicketTypesForCheckout(eventId: string) { const { user } = useContext(TropTixContext); const getTicketTypesType = GetTicketTypesType.GET_TICKET_TYPES_FOR_CHECKOUT; const id = eventId; @@ -47,7 +47,7 @@ export function useFetchTicketTypesForCheckout(eventId: string) { }); } -export async function checkOrderValidity( +async function checkOrderValidity( eventId: string, jwtToken: string | undefined, checkout: Checkout, @@ -106,7 +106,7 @@ export async function checkOrderValidity( }); } -export async function getTicketTypes({ +async function getTicketTypes({ getTicketTypesType, eventId, jwtToken, @@ -148,13 +148,13 @@ interface SaveTicketTypeError { status: number; } -export interface SaveTicketTypeResponse { +interface SaveTicketTypeResponse { success: boolean; data?: TicketType; error?: SaveTicketTypeError; } -export async function saveTicketType( +async function saveTicketType( ticketType: Partial, editTicketType: boolean ): Promise { diff --git a/apps/web/src/hooks/useUser.tsx b/apps/web/src/hooks/useUser.tsx index 8f574e21a..bb87cea7a 100644 --- a/apps/web/src/hooks/useUser.tsx +++ b/apps/web/src/hooks/useUser.tsx @@ -3,36 +3,36 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useContext } from 'react'; import { SocialMediaAccount, User } from './types/User'; -export enum GetUsersType { +enum GetUsersType { GET_USERS_BY_ID = 'GET_USERS_BY_ID', } -export type GetUsersRequest = { +type GetUsersRequest = { getUsersType: GetUsersType; userId?: string; }; -export enum PutUsersType { +enum PutUsersType { PUT_USERS_USER_DETAILS = 'PUT_USERS_USER_DETAILS', PUT_USERS_SOCIAL_MEDIA = 'PUT_USERS_SOCIAL_MEDIA', } -export type PutUsersRequest = { +type PutUsersRequest = { putUsersType: keyof typeof PutUsersType; socialMediaAccount?: SocialMediaAccount; user?: User; }; -export enum PostUsersType { +enum PostUsersType { POST_USERS_NEW_USER = 'POST_USERS_NEW_USER', } -export type PostUsersRequest = { +type PostUsersRequest = { postUsersType: keyof typeof PostUsersType; user?: User; }; -export function useFetchUserById(userId: string) { +function useFetchUserById(userId: string) { return useQuery({ queryKey: ['user', userId], queryFn: () => fetchUserById(userId), @@ -56,7 +56,7 @@ export function useFetchUser(): { }; } -export async function fetchUserById(userId: string) { +async function fetchUserById(userId: string) { const url = `/api/users?getUsersType=${GetUsersType.GET_USERS_BY_ID}&id=${userId}`; try { @@ -77,7 +77,7 @@ export async function fetchUserById(userId: string) { } } -export function useCreateUser(user: User) { +function useCreateUser(user: User) { const request: PostUsersRequest = { postUsersType: PostUsersType.POST_USERS_NEW_USER, user: user, @@ -85,7 +85,7 @@ export function useCreateUser(user: User) { return useMutation({ mutationFn: () => addUser(request) }); } -export async function addUser(request: PostUsersRequest) { +async function addUser(request: PostUsersRequest) { const url = '/api/users'; try { @@ -125,7 +125,7 @@ export function useUpdateUser() { }); } -export async function putUsers({ +async function putUsers({ putUsersType, socialMediaAccount, user, @@ -159,7 +159,7 @@ export async function putUsers({ } } -export function useUpdateUserSocialMedia() { +function useUpdateUserSocialMedia() { return useMutation({ mutationFn: (socialMediaAccount: SocialMediaAccount) => putUsers({ diff --git a/apps/web/src/lib/utils.ts b/apps/web/src/lib/utils.ts index 1ac4ef8ec..aa5a73315 100644 --- a/apps/web/src/lib/utils.ts +++ b/apps/web/src/lib/utils.ts @@ -8,11 +8,11 @@ export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } -export function getDateFormatter(date: Date) { +function getDateFormatter(date: Date) { return `${formatInTimeZone(date, 'America/New_York', 'MMM dd, yyyy, h:mm a')}`; } -export function getDateRangeFormatter(start: Date, end: Date) { +function getDateRangeFormatter(start: Date, end: Date) { const startDate = formatInTimeZone( start, 'America/New_York', @@ -31,7 +31,7 @@ export function getDateRangeFormatter(start: Date, end: Date) { return startDate; } -export function getTimeRangeFormatter(start: Date, end: Date) { +function getTimeRangeFormatter(start: Date, end: Date) { return `${formatInTimeZone(start, 'America/New_York', 'h:mm a')} - ${formatInTimeZone(end, 'America/New_York', 'h:mm a')}`; } @@ -53,7 +53,7 @@ export function generateId() { return uid.rnd(); } -export function generateJwtId() { +function generateJwtId() { const uid = new ShortUniqueId({ length: 16 }); return uid.rnd(); diff --git a/apps/web/src/pages/order-details/index.tsx b/apps/web/src/pages/order-details/index.tsx index 817d94a17..5166ead96 100644 --- a/apps/web/src/pages/order-details/index.tsx +++ b/apps/web/src/pages/order-details/index.tsx @@ -11,7 +11,7 @@ import { } from '@/hooks/useTicket'; import { getDateFormatter } from '@/lib/dateUtils'; import { getFormattedCurrency } from '@/lib/utils'; -import { RedoOutlined } from '@ant-design/icons'; +import { Hourglass, Loader2 } from 'lucide-react'; import { useQueryClient } from '@tanstack/react-query'; import { Button, Drawer, List, Result, Typography, message } from 'antd'; import Link from 'next/link'; @@ -134,7 +134,11 @@ export default function OrderDetailsPage() { return (
} + icon={ + + + + } title="Processing Order" className="mt-32" subTitle="Your order is currently processing so keep an eye out for your email confirmation and check back later. Please contact us if you have any further questions." diff --git a/apps/web/src/server/lib/auth.ts b/apps/web/src/server/lib/auth.ts index 2ef0e1493..5f8d2d869 100644 --- a/apps/web/src/server/lib/auth.ts +++ b/apps/web/src/server/lib/auth.ts @@ -61,7 +61,7 @@ export async function requireAuth( } } -export async function verifyJwtToken(request): Promise { +async function verifyJwtToken(request): Promise { let token = ''; if (request.headers.authorization) { const authorization = request.headers.authorization.split(' '); diff --git a/apps/web/src/server/lib/eventHelper.ts b/apps/web/src/server/lib/eventHelper.ts index 04d075980..b95ea302d 100644 --- a/apps/web/src/server/lib/eventHelper.ts +++ b/apps/web/src/server/lib/eventHelper.ts @@ -4,7 +4,7 @@ import { adminUserIds } from '@/server/lib/experimentHelper'; const prismaClient = prisma as PrismaClient; -export async function getAllEventsQuery(userId: string) { +async function getAllEventsQuery(userId: string) { if (adminUserIds.includes(userId)) { return prismaClient.events.findMany({ include: { @@ -37,7 +37,7 @@ export async function getAllEventsQuery(userId: string) { }); } -export async function getEventsScannableByOrganizerIdQuery(userId: string) { +async function getEventsScannableByOrganizerIdQuery(userId: string) { const organizedEvents = await prismaClient.events.findMany({ where: { organizerUserId: userId, @@ -67,7 +67,7 @@ export async function getEventsScannableByOrganizerIdQuery(userId: string) { return organizedEvents.concat(scannedEvents); } -export async function getEventsByOrganizerIdQuery(userId: string) { +async function getEventsByOrganizerIdQuery(userId: string) { const events = await prismaClient.events.findMany({ where: { organizerUserId: userId, @@ -97,7 +97,7 @@ export async function getEventsByOrganizerIdQuery(userId: string) { return events.concat(ownerEvents); } -export async function getEventByIdQuery(id: string) { +async function getEventByIdQuery(id: string) { return prismaClient.events.findUnique({ where: { id: id, @@ -155,7 +155,7 @@ export function getPrismaTicketTypeQuery(ticket) { return ticketInput; } -export function getPrismaUpdateEventQuery(event) { +function getPrismaUpdateEventQuery(event) { let eventInput: Prisma.EventsUpdateInput; eventInput = { imageUrl: event.imageUrl, @@ -178,7 +178,7 @@ export function getPrismaUpdateEventQuery(event) { return eventInput; } -export function getPrismaCreateStarterEventQuery(event) { +function getPrismaCreateStarterEventQuery(event) { let eventInput: Prisma.EventsCreateInput; eventInput = { diff --git a/apps/web/src/server/lib/orderHelper.ts b/apps/web/src/server/lib/orderHelper.ts index ffce30ef4..ad682467e 100644 --- a/apps/web/src/server/lib/orderHelper.ts +++ b/apps/web/src/server/lib/orderHelper.ts @@ -1,13 +1,13 @@ import { OrderStatus, Prisma, TicketStatus, TicketType } from '@prisma/client'; import { buffer } from 'micro'; -export const config = { +const config = { api: { bodyParser: false, }, }; -export async function getBuffer(request) { +async function getBuffer(request) { const buf = await buffer(request); return buf; } diff --git a/apps/web/src/server/lib/ticketHelper.ts b/apps/web/src/server/lib/ticketHelper.ts index 6e39cebd0..79210a596 100644 --- a/apps/web/src/server/lib/ticketHelper.ts +++ b/apps/web/src/server/lib/ticketHelper.ts @@ -93,7 +93,7 @@ export async function updateScannedTicketStatus( } } -export function getPrismaUpdateTicketUserQuery(userId) { +function getPrismaUpdateTicketUserQuery(userId) { let updatedTicket: Prisma.TicketsUpdateInput; updatedTicket = { diff --git a/apps/web/src/server/lib/userHelper.ts b/apps/web/src/server/lib/userHelper.ts index 4a17a419a..4d4028c55 100644 --- a/apps/web/src/server/lib/userHelper.ts +++ b/apps/web/src/server/lib/userHelper.ts @@ -3,7 +3,7 @@ import prisma from '@/server/prisma'; const prismaClient = prisma as PrismaClient; -export function addUserQuery() {} +function addUserQuery() {} export function getPrismaUpdateSocialMediaQuery(account) { let socialMedia: Prisma.SocialMediaAccountsUpdateInput; diff --git a/apps/web/src/types/Event.ts b/apps/web/src/types/Event.ts deleted file mode 100644 index 0cc2038d3..000000000 --- a/apps/web/src/types/Event.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { TicketType } from './TicketType'; -export type EventType = { - id: string; - createdAt: string; - updatedAt: string; - imageUrl: string; - name: string; - description: string; - organizer: string; - startDate: string; - startTime: string; - endDate: string; - endTime: string; - address: string; - country: string; - ticketTypes: TicketType[]; -}; diff --git a/apps/web/src/types/TicketType.ts b/apps/web/src/types/TicketType.ts deleted file mode 100644 index ff69302e6..000000000 --- a/apps/web/src/types/TicketType.ts +++ /dev/null @@ -1,16 +0,0 @@ -export type TicketType = { - id: string; - createdAt: string; - updatedAt: string; - name: string; - description: string; - maxPurchasePerUser: number; - quantity: number; - saleStartDate: string; - saleStartTime: string; - saleEndDate: string; - saleEndTime: string; - price: number; - ticketingFees: string; - eventId: string; -}; diff --git a/apps/web/src/types/checkout.ts b/apps/web/src/types/checkout.ts index 64103bb92..7a6e079e2 100644 --- a/apps/web/src/types/checkout.ts +++ b/apps/web/src/types/checkout.ts @@ -8,8 +8,7 @@ export enum ValidationResponseMessage { AllTicketsValidated = 'Tickets are available', AllTicketInvalid = 'All tickets are unavailable', NoTicketsSelected = 'No tickets selected', - MissingRequiredFields = 'Missing required fields or no tickets selected', -} + } export interface ValidationResponse { isValid: boolean; diff --git a/yarn.lock b/yarn.lock index b80e535e8..000fdce04 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5894,7 +5894,7 @@ "@types/node@20.6.0": version "20.6.0" - resolved "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.0.tgz#9d7daa855d33d4efec8aea88cd66db1c2f0ebe16" integrity sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg== "@types/node@^22.8.7": @@ -8609,6 +8609,15 @@ eastasianwidth@^0.2.0: resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +easy-table@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/easy-table/-/easy-table-1.2.0.tgz#ba9225d7138fee307bfd4f0b5bc3c04bdc7c54eb" + integrity sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww== + dependencies: + ansi-regex "^5.0.1" + optionalDependencies: + wcwidth "^1.0.1" + ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: version "1.0.11" resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz" @@ -8693,6 +8702,14 @@ enhanced-resolve@^5.12.0: graceful-fs "^4.2.4" tapable "^2.2.0" +enhanced-resolve@^5.18.1: + version "5.18.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf" + integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + entities@^4.4.0: version "4.5.0" resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" @@ -9550,7 +9567,7 @@ fast-glob@^3.2.12, fast-glob@^3.3.1: merge2 "^1.3.0" micromatch "^4.0.4" -fast-glob@^3.2.7, fast-glob@^3.3.2: +fast-glob@^3.2.7, fast-glob@^3.3.2, fast-glob@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== @@ -11952,6 +11969,11 @@ jiti@^1.18.2: resolved "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz" integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== +jiti@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.4.2.tgz#d19b7732ebb6116b06e2038da74a55366faef560" + integrity sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A== + jju@^1.1.0: version "1.4.0" resolved "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz" @@ -12316,6 +12338,26 @@ kleur@^3.0.3: resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +knip@^5.50.5: + version "5.50.5" + resolved "https://registry.yarnpkg.com/knip/-/knip-5.50.5.tgz#cd4b6573eafaa63bdeff3cc8f203ed813107d84a" + integrity sha512-I3mfebuG5x8i/mJJA41xjnmHMbLw75ymbDxlS7HMP+4CjY+jXEDSJyP3A2xmI5JF5/o47Fr8D7Pq3BVT0/nQPw== + dependencies: + "@nodelib/fs.walk" "^1.2.3" + easy-table "1.2.0" + enhanced-resolve "^5.18.1" + fast-glob "^3.3.3" + jiti "^2.4.2" + js-yaml "^4.1.0" + minimist "^1.2.8" + picocolors "^1.1.0" + picomatch "^4.0.1" + pretty-ms "^9.0.0" + smol-toml "^1.3.1" + strip-json-comments "5.0.1" + zod "^3.22.4" + zod-validation-error "^3.0.3" + kuler@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz" @@ -13079,7 +13121,7 @@ minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.6, minimist@^1.2.8: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -13804,6 +13846,11 @@ parse-ms@^2.1.0: resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-2.1.0.tgz#348565a753d4391fa524029956b172cb7753097d" integrity sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA== +parse-ms@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-4.0.0.tgz#c0c058edd47c2a590151a718990533fd62803df4" + integrity sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw== + parse-svg-path@^0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz" @@ -13983,12 +14030,17 @@ picocolors@^1.0.1: resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz" integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== +picocolors@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -picomatch@^4.0.2: +picomatch@^4.0.1, picomatch@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== @@ -14174,6 +14226,13 @@ pretty-ms@7.0.1: dependencies: parse-ms "^2.1.0" +pretty-ms@^9.0.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-9.2.0.tgz#e14c0aad6493b69ed63114442a84133d7e560ef0" + integrity sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg== + dependencies: + parse-ms "^4.0.0" + prisma@^5.14.0: version "5.14.0" resolved "https://registry.npmjs.org/prisma/-/prisma-5.14.0.tgz" @@ -15941,6 +16000,11 @@ smart-buffer@^4.2.0: resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== +smol-toml@^1.3.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/smol-toml/-/smol-toml-1.3.4.tgz#4ec76e0e709f586bc50ba30eb79024173c2b2221" + integrity sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA== + socks-proxy-agent@^8.0.2, socks-proxy-agent@^8.0.3: version "8.0.3" resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz" @@ -16300,6 +16364,11 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" +strip-json-comments@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-5.0.1.tgz#0d8b7d01b23848ed7dbdf4baaaa31a8250d8cfa0" + integrity sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw== + strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" @@ -16988,7 +17057,7 @@ typescript@4.9.5: typescript@5.2.2: version "5.2.2" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== typescript@^5.2.2: @@ -17808,7 +17877,12 @@ zip-stream@^4.1.0: compress-commons "^4.1.2" readable-stream "^3.6.0" -zod@^3.24.3: +zod-validation-error@^3.0.3: + version "3.4.0" + resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-3.4.0.tgz#3a8a1f55c65579822d7faa190b51336c61bee2a6" + integrity sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ== + +zod@^3.22.4, zod@^3.24.3: version "3.24.3" resolved "https://registry.yarnpkg.com/zod/-/zod-3.24.3.tgz#1f40f750a05e477396da64438e0e1c0995dafd87" integrity sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==