Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/scanner-logos #254

Merged
merged 5 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/admin/scan/scan-client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const ScanClient = () => {
? <QrReader active={scannerActive} updateFunction={(value) => {setScannedResult(value)}}></QrReader>
: <FakeScanner/> }
{ scannerActive
? <div>Scanning... {scannedResult}</div>
? <div>Scanner Active {scannedResult}</div>
: <ScanSuccessDialog scan={scannedResult} onClick={() => {setScannerActive(true), setScannedResult('')}} />
}
</div>
Expand Down
4 changes: 2 additions & 2 deletions app/api/admin/attendees/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { currentUser } from '@clerk/nextjs/server';
import { guaranteeISOstringFromDate } from '@lib/useful';

export async function GET() {
const {userId} = auth();
const {userId} = await auth();

if(!userId){
return Response.json({error: "User is not signed in."}, { status: 401 });
Expand Down Expand Up @@ -62,7 +62,7 @@ export async function GET() {

export async function POST(req: NextRequest) {
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY });
const {userId} = auth();
const {userId} = await auth();

if(!userId){
return Response.json({error: "User is not signed in."}, { status: 401 });
Expand Down
2 changes: 1 addition & 1 deletion app/api/admin/meal/summary/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { NextRequest } from 'next/server';

export async function GET(_req: NextRequest) {
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY });
const {userId} = auth();
const {userId} = await auth();

if(!userId){
return Response.json({error: "User is not signed in."}, { status: 401 });
Expand Down
2 changes: 1 addition & 1 deletion app/api/admin/meal/trigger/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { NextRequest } from 'next/server';

export async function POST(_req: NextRequest) {
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY });
const {userId} = auth();
const {userId} = await auth();

if(!userId){
return Response.json({error: "User is not signed in."}, { status: 401 });
Expand Down
10 changes: 5 additions & 5 deletions app/api/admin/scan/[ticket_number]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { currentUser } from '@clerk/nextjs/server';
import { getUnixTime } from 'date-fns';

export async function GET(_req: NextRequest,{params}: {params: {ticket_number: string}}) {
const {userId} = auth();
const {userId} = await auth();

if(!userId){
return Response.json({error: "User is not signed in."}, { status: 401 });
return Response.json({error: "User is not signed in to GET."}, { status: 401 });
}

const user = await currentUser();
if(!user){
return Response.json({error: "User is not signed in!"}, { status: 401 });
return Response.json({error: "User is not signed in to GET user details!"}, { status: 401 });
}
if(!user.publicMetadata.admin){
return Response.json({error: "User is does not have list tickets permissions."}, { status: 401 });
Expand All @@ -37,10 +37,10 @@ console.log(scanUrl)

export async function POST(req: NextRequest,{params}: {params: {ticket_number: string}}) {
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY });
const {userId} = auth();
const {userId} = await auth();

if(!userId){
return Response.json({error: "User is not signed in."}, { status: 401 });
return Response.json({error: "User is not signed in to POST change."}, { status: 401 });
}

const requestingUser = await clerkClient.users.getUser(userId);
Expand Down
4 changes: 2 additions & 2 deletions app/api/admin/stripe/products/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

export async function GET(_req: NextRequest) {
const {userId} = auth();
const {userId} = await auth();
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY });

if(!userId){
Expand All @@ -22,7 +22,7 @@ export async function GET(_req: NextRequest) {


// export async function POST(_req: NextRequest) {
// const {userId} = auth();
// const {userId} = await auth();
// const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY });

// if(!userId){
Expand Down
2 changes: 1 addition & 1 deletion app/api/admin/stripe/webhook/[stripe_id]/[status]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

export async function POST(_req: NextRequest, {params}:{ params: { stripe_id: string, status: string } }) {
const {userId} = auth();
const {userId} = await auth();
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY });

if(!userId){
Expand Down
4 changes: 2 additions & 2 deletions app/api/admin/stripe/webhooks/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

export async function GET(_req: NextRequest) {
const {userId} = auth();
const {userId} = await auth();
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY });

if(!userId){
Expand All @@ -25,7 +25,7 @@ export async function GET(_req: NextRequest) {


export async function POST(_req: NextRequest) {
const {userId} = auth();
const {userId} = await auth();
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY });

if(!userId){
Expand Down
4 changes: 2 additions & 2 deletions app/api/admin/users/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { NextRequest } from 'next/server';

export async function GET() {
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY });
const {userId} = auth();
const {userId} = await auth();

if(!userId){
return Response.json({error: "User is not signed in."}, { status: 401 });
Expand Down Expand Up @@ -38,7 +38,7 @@ export async function GET() {

export async function POST(req: NextRequest) {
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY });
const {userId} = auth();
const {userId} = await auth();

if(!userId){
return Response.json({error: "User is not signed in."}, { status: 401 });
Expand Down
2 changes: 1 addition & 1 deletion app/api/ticket/update/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { NextRequest, NextResponse } from 'next/server';
import { currentUser } from '@clerk/nextjs/server';

export async function POST(req: NextRequest) {
const {userId} = auth();
const {userId} = await auth();

// Setup context
const reqData = await req.json();
Expand Down
6 changes: 3 additions & 3 deletions components/admin/attendeeStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ export default function AttendeeStats() {
{ name: 'Dinner Prefs', value: 'Error', unit: '' }
] as StatLine[]
: [
{ name: 'Total', value: data.attendees.length, unit: 'tickets' },
{ name: 'This week', value: data.attendees.filter((row)=>{
{ name: 'Total', value: data.attendees?.length, unit: 'tickets' },
{ name: 'This week', value: data.attendees?.filter((row)=>{
return guaranteeTimestampFromDate(row.purchased_date) > subWeeks(new Date(),1).getTime()
}).length, unit: 'tickets' },
{ name: 'Meal prefs', value: data.attendees.filter((row)=>{return row.meal_preferences}).length, unit: 'set' },
{ name: 'Meal prefs', value: data.attendees?.filter((row)=>{return row.meal_preferences}).length, unit: 'set' },
{ name: 'Dinner Prefs', value: 'Unknown', unit: '' }
] as StatLine[]

Expand Down
71 changes: 58 additions & 13 deletions components/admin/scan/ScanSuccessDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,43 @@
import useSWR from "swr";
import { itemsFromPassCombination} from '@components/ticketing/pricingUtilities'
import { format } from "date-fns";
// import { itemsFromPassCombination} from '@components/ticketing/pricingUtilities'
import { format, fromUnixTime } from "date-fns";
import { fetcher, scanIn } from "@lib/fetchers";
// const fetcher = (url: string) => fetch(url).then((res) => res.json());

export type line_item = {
description: string,
}
const accessToWristbands = (accesCode: number[], line_items: line_item[]) => {
let wristBands = []
const meal = accesCode[2] > 0
const friday = accesCode[0] > 0
const artist = line_items.filter((li) => { return /Artist/.test(li.description)}).length > 0
const staffPass = line_items.filter((li) => { return /Staff/.test(li.description) || /Volunteer/.test(li.description)}).length > 0
const fullPass = line_items.filter((li) => { return /Full/.test(li.description)}).length > 0
const partyPass = line_items.filter((li) => { return /Party\sPass/.test(li.description)}).length > 0
const classPass = line_items.filter((li) => { return /Class\sPass/.test(li.description)}).length > 0
const saturdayPass = line_items.filter((li) => { return /Saturday\sPass/.test(li.description) }).length > 0
const sundayPass = line_items.filter((li) => { return /Sunday\sPass/.test(li.description) }).length > 0
const saturdayClass = line_items.filter((li) => { return /Saturday\s-\sClass/.test(li.description) }).length > 0
const saturdayParty = line_items.filter((li) => { return /Saturday\s-\sParty/.test(li.description) || /Dine\sand\sDance\sPass/.test(li.description) }).length > 0
const sundayClass = line_items.filter((li) => { return /Sunday\s-\sClass/.test(li.description) }).length > 0
const sundayParty = line_items.filter((li) => { return /Sunday\s-\sParty/.test(li.description) }).length > 0


if(meal) { wristBands.push({ colour: "bg-white text-black", name: "Dinner - Ticket"}) }
if(friday && !artist && !staffPass && !fullPass && !partyPass) { wristBands.push({ colour: "bg-black", name: "Friday - Stamp"}) }
if(artist) { wristBands.push({ colour: "bg-blue-600", name: "Artist Pass - Plastic"}) }
if(staffPass) { wristBands.push({ colour: "bg-blue-600", name: "Staff/Volunteer Pass - Plastic"}) }
if(fullPass) { wristBands.push({ colour: "bg-gray-300 text-black", name: "Full Pass - Plastic"}) }
if(partyPass) { wristBands.push({ colour: "bg-orange-700", name: "Party Pass - Plastic"}) }
if(classPass) { wristBands.push({ colour: "bg-orange-400 text-black", name: "Class Pass - Paper"}) }
if(saturdayPass) { wristBands.push({ colour: "bg-purple-700", name: "Saturday Pass - Plastic"}) }
if(sundayPass) { wristBands.push({ colour: "bg-yellow-300 text-black", name: "Sunday Pass - Paper"}) }
if(saturdayClass) { wristBands.push({ colour: "bg-pink-400 text-black", name: "Saturday Class - Paper"}) }
if(saturdayParty) { wristBands.push({ colour: "bg-green-950", name: "Saturday Party - Paper"}) }
if(sundayClass) { wristBands.push({ colour: "bg-green-400", name: "Sunday Class - Plastic"}) }
if(sundayParty) { wristBands.push({ colour: "bg-blue-800", name: "Sunday Party - Paper"}) }
return wristBands
}

const ScanSuccessDialog = ({scan,onClick}) => {
const {data, error, isLoading, isValidating} = useSWR(`/api/admin/scan/${scan}`, fetcher, { keepPreviousData: false });
Expand All @@ -16,32 +51,42 @@ const ScanSuccessDialog = ({scan,onClick}) => {
const attendee = data.attendee
const goodResult = attendee.active && !attendee.ticket_used
const student = attendee.student_ticket
const access = itemsFromPassCombination(attendee.line_items.map(item => item.description))
const checked_in = attendee.ticket_used ? format(attendee.ticket_used, 'dd MMMM yyyy') : attendee.ticket_used
const wristBands = accessToWristbands(attendee.access,attendee.line_items)
// const access = itemsFromPassCombination(attendee.line_items.map(item => item.description))
const checked_in = attendee.ticket_used ? format(fromUnixTime(attendee.ticket_used), 'HH:mm:ss do MMM') : attendee.ticket_used
const cardColor = isLoading ? "bg-gray-500" : goodResult ? student ? "bg-green-600" : "bg-green-500" : "bg-chillired-600"
const cancelButton = checked_in ? "border-red-900 text-red-900" : "border-green-900 text-green-900"
const checkinButton = checked_in ? "bg-red-950" : "bg-green-950"

return (<div className="absolute top-0 left-0 bg-gradient-to-b from-richblack-500 to-richblack-500 w-full px-3 mb-12">
<div className={`rounded-xl p-8 w-full flex flex-col justify-between ${cardColor}`}>
<div>
<div className={`rounded-xl p-4 w-full flex flex-col justify-between ${cardColor}`}>
<div className="p-4">
<h1 className="text-2xl md:text-5xl font-bold leading-tight">{attendee.full_name}</h1>
<h2 className="text-xl md:text-4xl">{attendee.ticket_number}</h2>
{ checked_in ? <div className="text-xl">Checked in already: {checked_in}</div>: <ul className="text-lg list-disc list-inside mt-3">
{access.map(item => <li key={item}>{item}</li>)}
</ul>}
<h2 className="text-lg md:text-2xl">{attendee.ticket_number}</h2>
{ checked_in ? <div className="text-xl">Checked in already: {checked_in}</div>: <div>
{/* <ul className="text-lg list-disc list-inside mt-3">
{access.map(item => <li className="text-sm" key={item}>{item}</li>)}
</ul> */}
{ wristBands.map((wristBand) => {
return (<div key={wristBand.name} className={`${wristBand.colour} rounded w-full p-2`}>{wristBand.name}</div>)
})}
</div>
}

</div>
<div className="actions flex w-full justify-stretch gap-6 mt-6">
{student ? <div className="">Student Ticket Check ID</div> : null}
<button className={`${cancelButton} border rounded px-4 py-4 w-full text-lg md:text-xl`} onClick={onClick}>Cancel</button>
<button className={`${checkinButton} rounded px-4 py-4 w-full text-lg md:text-xl`} onClick={() => {scanIn(attendee.ticket_number,attendee.email, checked_in ? true : false); onClick();}}>{checked_in ? "Reset" : "Check in"}</button>
</div>
{/* {data ? <pre className="text-xs">Ticket: {JSON.stringify(data,null,2)}</pre> : <div className="text-white text-xl">Loading</div>} */}
</div>
</div>)
} else {
return <div>Nutting!</div>
return <div>Nothing</div>
}

}

export default ScanSuccessDialog
export default ScanSuccessDialog

4 changes: 2 additions & 2 deletions middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ const isProtectedRoute = createRouteMatcher([
'/admin(.*)',
]);

export default clerkMiddleware((auth, req) => {
if (isProtectedRoute(req)) auth().protect();
export default clerkMiddleware(async (auth, req) => {
if (isProtectedRoute(req)) await auth().protect();
});

// See "Matching Paths" below to learn more
Expand Down
Loading