diff --git a/src/app/(layout-free)/event/[slug]/kiosk/kiosk-form.tsx b/src/app/(layout-free)/event/[slug]/kiosk/kiosk-form.tsx deleted file mode 100644 index e70ef0c..0000000 --- a/src/app/(layout-free)/event/[slug]/kiosk/kiosk-form.tsx +++ /dev/null @@ -1,214 +0,0 @@ -"use client"; - -import { Button } from "@/components/ui/button"; -import { useState } from "react"; -import { Selection } from "../../../../../components/menu-select"; - -import { MenuItem as MenuItemInterface } from "@/config/menus"; -import MultiSelect from "@/components/ui/multi-select"; -import { Label } from "@/components/ui/label"; -import { Input } from "@/components/ui/input"; -import { useToast } from "@/components/ui/use-toast"; -import MenuItem from "@/app/(layout-free)/event/[slug]/menu/menu-item"; -import { Checkbox } from "@/components/ui/checkbox"; -import { MessageCircleMoreIcon, MessageSquareIcon } from "lucide-react"; - -export default function OrderForm({ - selection, - eventSlug, -}: { - selection: Selection; - eventSlug: string; -}) { - const [pending, setPending] = useState(false); - - const { toast } = useToast(); - const [order, setOrder] = useState<{ - item: MenuItemInterface; - phone: string; - event: string; - modifiers: any[]; - whatsapp: boolean; - agreed: boolean; - }>({ - item: { - title: "", - shortTitle: "", - description: "", - }, - event: eventSlug, - phone: "", - modifiers: [], - whatsapp: true, - agreed: false, - }); - - const incomplete = - !order.item || !order.phone || !order.agreed || !order.item?.title; - - return ( -
-
- {selection?.items.map((item: MenuItemInterface, index: Number) => ( -
{ - setOrder({ ...order, item: item }); - }} - className={`px-10 pb-8 rounded-lg mb-2 ${item.title === order.item?.title ? "bg-gray-400" : "bg-gray-200"} `} - // {/* Use these parameters to adapt to a different screen size */} - // and also font size and space-y-8 above - > - -
- ))} -
- {selection.modifiers.length > 0 && ( - <> - - { - return { label: m, value: m }; - })} - onChange={(selected) => { - //@ts-ignore - setOrder({ ...order, modifiers: selected }); - }} - /> - - )} - -
- ) => - setOrder({ ...order, phone: e.target.value }) - } - /> - { - setOrder({ ...order, whatsapp: !order.whatsapp }); - }} - > - {order.whatsapp ? "via WhatsApp" : "via SMS"} - - - -
- -
- { - setOrder({ ...order, agreed: checked }); - }} - /> - -
- - -
- ); -} diff --git a/src/app/(layout-free)/event/[slug]/kiosk/page.tsx b/src/app/(layout-free)/event/[slug]/kiosk/page.tsx index ee9048c..96812f0 100644 --- a/src/app/(layout-free)/event/[slug]/kiosk/page.tsx +++ b/src/app/(layout-free)/event/[slug]/kiosk/page.tsx @@ -1,7 +1,7 @@ import { Privilege } from "@/middleware"; import { cookies } from "next/headers"; -import OrderForm from "./kiosk-form"; import { getSyncService } from "@/lib/twilio"; +import OrderForm from "@/app/(master-layout)/event/[slug]/orders/order-form"; export default async function KioskPage(props: { params: Promise<{ slug: string }>; @@ -29,12 +29,13 @@ export default async function KioskPage(props: { return (
-

Welcome to SIGNAL London!

- Order your coffee here and pick it up at the barista station. + Order your beverage here and pick it up at the Twilio booth.

{hasPermissions && ( diff --git a/src/app/(master-layout)/event/[slug]/orders/ordersList.tsx b/src/app/(master-layout)/event/[slug]/orders/ordersList.tsx index e2c80aa..ee9ee14 100644 --- a/src/app/(master-layout)/event/[slug]/orders/ordersList.tsx +++ b/src/app/(master-layout)/event/[slug]/orders/ordersList.tsx @@ -247,7 +247,6 @@ export default function OrdersList({ data.item.shortTitle, index, ); - debugger; addMessageToConversation( data.key, "", diff --git a/src/app/api/kioskOrder/route.ts b/src/app/api/kioskOrder/route.ts deleted file mode 100644 index 45c8120..0000000 --- a/src/app/api/kioskOrder/route.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { headers } from "next/headers"; - -import { - addMessageToConversation, - createConversationWithParticipant, - getConversationsOfSender, - getLookupService, - getSyncService, - pushToSyncList, - updateOrCreateSyncMapItem, -} from "@/lib/twilio"; -import { Privilege, getAuthenticatedRole } from "@/middleware"; -import { - getCountryFromPhone, - redact, - Stages, - TwoWeeksInSeconds, -} from "@/lib/utils"; -import { Order } from "@/config/menus"; -import { getOrderCreatedMessage } from "@/scripts/fetchContentTemplates"; - -const NEXT_PUBLIC_ACTIVE_CUSTOMERS_MAP = - process.env.NEXT_PUBLIC_ACTIVE_CUSTOMERS_MAP || ""; - -export async function POST(request: Request) { - const [headersList, data] = await Promise.all([headers(), request.json()]); - const role = getAuthenticatedRole(headersList.get("Authorization") || ""); - - const isPrivileged = [Privilege.ADMIN, Privilege.KIOSK].includes(role); - - if (!process.env.NEXT_PUBLIC_EVENTS_MAP) { - console.error("No config doc specified"); - return new Response("No config doc specified", { - status: 500, - statusText: "No config doc specified", - }); - } - if (!isPrivileged) { - console.error("Not authorized"); - return new Response( - `Role ${role} is not authorized to perform this action`, - { - status: 500, - statusText: `Role ${role} is not authorized to perform this action`, - }, - ); - } - - // 1. Validate user input - const lookupService = await getLookupService(); - const lookupResult = await lookupService - .phoneNumbers(data.phone) - .fetch({ fields: "sms_pumping_risk" }); - if (!data.phone || !data?.item?.title || !data.event) { - return new Response("Missing required fields", { - status: 400, - statusText: "Missing required fields", - }); - } - - if (!lookupResult.valid) { - return new Response("Phone number is invalid", { - status: 400, - statusText: "Phone number is invalid", - }); - } - if (lookupResult?.smsPumpingRisk?.sms_pumping_risk_score >= 60) { - return new Response( - "Phone number is at high risk of SMS pumping. Please try again later.", - { - status: 400, - statusText: - "Phone number is at high risk of SMS pumping. Please try again later.", - }, - ); - } - - // 2. Fetch event data - const syncService = await getSyncService(); - const events = await syncService - .syncMaps()(process.env.NEXT_PUBLIC_EVENTS_MAP) - .fetch(); - const items = await events.syncMapItems().list(); - const event = items.find((item: any) => item.data.slug === data.event); - - if (!event) { - return new Response("Event not found", { - status: 404, - statusText: "Event not found", - }); - } - - // 3. Create new conversation - const sender = data.whatsapp - ? `whatsapp:${lookupResult.phoneNumber}` - : lookupResult.phoneNumber; - const participantConversations = await getConversationsOfSender(sender); - const activeConversations = participantConversations.filter( - (conv) => conv.conversationState === "active", - ); - let conversationSid; - if (activeConversations.length === 0) { - // create a new conversation - const senders = event?.data?.senders; - const phoneNumber = senders?.find((s: string) => !s.startsWith("whatsapp")); // assuming here that this sender is also whatsapp-enabled - try { - const c = await createConversationWithParticipant(sender, phoneNumber); - conversationSid = c.sid; - } catch (e) { - console.error(e); - return new Response("Failed to create conversation", { - status: 500, - statusText: "Failed to create conversation", - }); - } - } else { - // add message to existing conversation - conversationSid = activeConversations[0].conversationSid; - } - - // 4. Add attendee to sync list - // incorrect but doesn't matter for this single-use event, should check if attendee is already in list - try { - const country = getCountryFromPhone(lookupResult.phoneNumber); - await updateOrCreateSyncMapItem( - NEXT_PUBLIC_ACTIVE_CUSTOMERS_MAP, - conversationSid, - { - event: data.event, - orderCount: 1, - stage: Stages.FIRST_ORDER, - country: country?.name === "Canada" ? "United States" : country?.name, - }, - TwoWeeksInSeconds, - ); - } catch (e) { - console.error(e); - return new Response("Failed to add attendee to sync list", { - status: 500, - statusText: "Failed to add attendee to sync list", - }); - } - - // 5. Add order to sync list - let orderNumber; - try { - const order: Order = { - key: conversationSid, - address: await redact(sender), - item: data.item, - ...(data?.modifiers?.length >= 1 && { modifiers: data.modifiers }), - status: "queued", - originalText: "Ordered via Kiosk", - }; - const receipt = await pushToSyncList(data.event, order); - orderNumber = receipt.index; - } catch (e) { - console.error(e); - return new Response("Failed to add order to sync list", { - status: 500, - statusText: "Failed to add order to sync list", - }); - } - - // 6. Send order confirmation message - try { - const message = await getOrderCreatedMessage( - data.item.shortTitle, - orderNumber, - event?.data?.selection?.mode, - ); - - await addMessageToConversation( - conversationSid, - undefined, - message.contentSid, - message.contentVariables, - ); - } catch (e) { - console.error(e); - return new Response("Failed to send order confirmation message", { - status: 500, - statusText: "Failed to send order confirmation message", - }); - } - return new Response(null, { status: 201 }); -}