diff --git a/src/app/harbor/tabs/tabs.tsx b/src/app/harbor/tabs/tabs.tsx
index 99e8c1b8..9e7637f5 100644
--- a/src/app/harbor/tabs/tabs.tsx
+++ b/src/app/harbor/tabs/tabs.tsx
@@ -226,7 +226,7 @@ export default function Harbor({
{
name: <>Tavern 🍻>,
path: 'tavern',
- component: ,
+ component: , //,
// component: process.env.NEXT_PUBLIC_LOW_RATE_LIMIT ? (
//
// ) : (
diff --git a/src/app/harbor/tavern/tavern-utils.ts b/src/app/harbor/tavern/tavern-utils.ts
index 8f53ba79..ab66623b 100644
--- a/src/app/harbor/tavern/tavern-utils.ts
+++ b/src/app/harbor/tavern/tavern-utils.ts
@@ -1,6 +1,11 @@
'use server'
import { getSession } from '@/app/utils/auth'
+import {
+ setTavernRsvpStatus,
+ submitMyTavernLocation,
+ submitShirtSize,
+} from '@/app/utils/tavern'
import Airtable from 'airtable'
Airtable.configure({
@@ -8,7 +13,7 @@ Airtable.configure({
endpointUrl: process.env.AIRTABLE_ENDPOINT_URL,
})
-type RsvpStatus = 'none' | 'organizer' | 'participant'
+export type RsvpStatus = 'none' | 'organizer' | 'participant'
export type TavernPersonItem = {
status: RsvpStatus
coordinates: string
@@ -102,3 +107,19 @@ export const getTavernEvents = async () => {
lastEventsFetch = Date.now()
return items
}
+
+export async function rspvForTavern(formData: FormData) {
+ let res = { success: true, error: null }
+
+ await Promise.all([
+ setTavernRsvpStatus(formData.get('rsvp') as RsvpStatus),
+ submitMyTavernLocation(formData.get('tavern') as string),
+ submitShirtSize(formData.get('shirt') as string),
+ ]).catch((error) => {
+ console.error('Error submitting tavern RSVP', error)
+ res = { success: false, error: error.toString() }
+ })
+
+ console.log('Successfully saved tavern RSVP')
+ return JSON.stringify(res)
+}
diff --git a/src/app/harbor/tavern/tavern.tsx b/src/app/harbor/tavern/tavern.tsx
index 231b07a9..a5a6b1b0 100644
--- a/src/app/harbor/tavern/tavern.tsx
+++ b/src/app/harbor/tavern/tavern.tsx
@@ -15,8 +15,10 @@ import dynamic from 'next/dynamic'
import {
getTavernEvents,
getTavernPeople,
+ rspvForTavern,
TavernEventItem,
TavernPersonItem,
+ RsvpStatus,
} from './tavern-utils'
import Modal from '@/components/ui/modal'
import { Button } from '@/components/ui/button'
@@ -27,63 +29,77 @@ const Map = dynamic(() => import('./map'), {
ssr: false,
})
-const RsvpStatusSwitcher = ({ tavernEvents, onTavernSelect }) => {
- const [rsvpStatus, setRsvpStatus] = useLocalStorageState(
- 'cache.rsvpStatus',
- 'none',
- )
- const [whichTavern, setWhichTavern] = useLocalStorageState(
- 'cache.whichTavern',
- 'none',
- )
- const [shirtSize, setShirtSize] = useLocalStorageState(
- 'cache.shirtSize',
- 'none',
- )
+type TavernDatafetchCategory =
+ | 'rsvpStatus'
+ | 'tavernEvents'
+ | 'myTavernLocation'
+ | 'tavernPeople'
+ | 'shirtSize'
+
+const RsvpStatusSwitcher = ({
+ rsvpStatus,
+ setRsvpStatus,
+ tavernEvents,
+ selectedTavern,
+ setSelectedTavern,
+ shirtSize,
+ setShirtSize,
+ erroredFetches,
+}: {
+ rsvpStatus: RsvpStatus
+ setRsvpStatus: (status: RsvpStatus) => void
+ tavernEvents: TavernEventItem[]
+ selectedTavern: TavernEventItem | null
+ setSelectedTavern: (tavernId: string | null) => void
+ shirtSize: any
+ setShirtSize: (size: string) => void
+ erroredFetches: TavernDatafetchCategory[]
+}) => {
+ const [editedFlag, setEditedFlag] = useState(false)
const [attendeeNoOrganizerModal, setAttendeeNoOrganizerModal] =
useState(false)
const { toast } = useToast()
- useEffect(() => {
- toast({
- title: 'Saved',
- description:
- editMessages[Math.floor(Math.random() * editMessages.length)],
- })
- }, [rsvpStatus, whichTavern, shirtSize])
- useEffect(() => {
- // set rsvp status
- getTavernRsvpStatus().then((status) => setRsvpStatus(status))
- getShirtSize().then((ss) => setShirtSize(ss))
- }, [])
+ // useEffect(() => {
+ // toast({
+ // title: 'Saved',
+ // description:
+ // editMessages[Math.floor(Math.random() * editMessages.length)],
+ // })
+ // }, [rsvpStatus, whichTavern, shirtSize])
- const onOptionChangeHandler = (e) => {
- const status = e.target.value
- setRsvpStatus(status)
- setTavernRsvpStatus(status)
+ // useEffect(() => {
+ // // set rsvp status
+ // getShirtSize().then((ss) => setShirtSize(ss))
+ // }, [])
- if (status !== 'participant' && status !== 'organizer') {
- setWhichTavern('none')
- submitMyTavernLocation(null)
- onTavernSelect(null)
- }
- }
+ // const onOptionChangeHandler = (e) => {
+ // const status = e.target.value
+ // setRsvpStatus(status)
+ // setTavernRsvpStatus(status)
- const onTavernChangeHandler = (event) => {
- const tavernId = event.target.value
- setWhichTavern(tavernId)
- submitMyTavernLocation(tavernId).catch(console.error)
- onTavernSelect(tavernId)
-
- if (
- rsvpStatus === 'participant' &&
- tavernEvents.find((te) => te.id === tavernId).organizers.length === 0
- ) {
- console.log('u shoiuld vhe an organizer')
- setAttendeeNoOrganizerModal(true)
- }
- }
+ // if (status !== 'participant' && status !== 'organizer') {
+ // setWhichTavern('none')
+ // submitMyTavernLocation(null)
+ // onTavernSelect(null)
+ // }
+ // }
+
+ // const onTavernChangeHandler = (event) => {
+ // const tavernId = event.target.value
+ // setWhichTavern(tavernId)
+ // submitMyTavernLocation(tavernId).catch(console.error)
+ // onTavernSelect(tavernId)
+
+ // if (
+ // rsvpStatus === 'participant' &&
+ // tavernEvents.find((te) => te.id === tavernId).organizers.length === 0
+ // ) {
+ // console.log('u shoiuld vhe an organizer')
+ // setAttendeeNoOrganizerModal(true)
+ // }
+ // }
const eventsByCountry = tavernEvents.reduce((acc, event) => {
const country = event.locality.split(', ').at(-1)
@@ -110,25 +126,154 @@ const RsvpStatusSwitcher = ({ tavernEvents, onTavernSelect }) => {
Please consider volunteering to organize this tavern, me hearty!
-
{
+ const rsvpResponse = JSON.parse(await rspvForTavern(formData))
+
+ if (rsvpResponse.success) {
+ toast({
+ title: 'Saved',
+ description:
+ editMessages[Math.floor(Math.random() * editMessages.length)],
+ })
+ } else {
+ toast({
+ title: 'Error',
+ description: `Failed to save your changes:\n${rsvpResponse.error}`,
+ })
+ }
+ }}
+ className="flex flex-col justify-items-stretch"
+ >
+ {erroredFetches.includes('rsvpStatus') ? (
+
+ Failed to load your current RSVP status.
+
+ ) : !rsvpStatus ? (
+
Loading RSVP status selection...
+ ) : (
+ <>
+
+
+ {rsvpStatus === 'participant' || rsvpStatus === 'organizer' ? (
+ <>
+
+ {erroredFetches.includes('tavernEvents') ? (
+
+ Failed to fetch tavern events
+
+ ) : erroredFetches.includes('myTavernLocation') ? (
+
+ Failed to fetch your tavern location
+
+ ) : !tavernEvents || !selectedTavern ? (
+
Loading tavern events selection...
+ ) : (
+
+ )}
+
+
+
+ {erroredFetches.includes('shirtSize') ? (
+
+ Failed to fetch your shirt size
+
+ ) : !shirtSize ? (
+
Loading shirt size selection...
+ ) : (
+
+ )}
+
+ >
+ ) : null}
+ >
+ )}
+
+
+ {editedFlag ? (
+
You have unsaved changes!
+ ) : null}
+
+
+
+
+
+ {/*
-
+
{tavernEvents &&
(rsvpStatus === 'participant' || rsvpStatus === 'organizer') ? (
@@ -178,29 +323,67 @@ const RsvpStatusSwitcher = ({ tavernEvents, onTavernSelect }) => {
>
) : null}
-
+
*/}
>
)
}
export default function Tavern() {
+ const [rsvpStatus, setRsvpStatus] = useLocalStorageState(
+ 'cache.rsvpStatus',
+ 'none',
+ )
const [tavernPeople, setTavernPeople] = useState([])
const [tavernEvents, setTavernEvents] = useState([])
const [selectedTavern, setSelectedTavern] = useState(
null,
)
+ const [shirtSize, setShirtSize] = useLocalStorageState(
+ 'cache.shirtSize',
+ 'none',
+ )
+ const [erroredFetches, setErroredFetches] = useState<
+ TavernDatafetchCategory[]
+ >([])
useEffect(() => {
- Promise.all([
- getTavernPeople(),
- getTavernEvents(),
- getMyTavernLocation(),
- ]).then(([tp, te, myTavernLocation]) => {
- setTavernPeople(tp)
- setTavernEvents(te)
- setSelectedTavern(myTavernLocation)
- console.log("ARRR TH TAVERN YE BE GOEN T' BE", myTavernLocation)
- })
+ getTavernRsvpStatus()
+ .then((d) => {
+ console.log({ travernrspv: d })
+ setRsvpStatus(d)
+ })
+ .catch((err: Error) => {
+ console.error(err)
+ setErroredFetches((p) => [...p, 'rsvpStatus'])
+ })
+
+ getTavernEvents()
+ .then(setTavernEvents)
+ .catch((err: Error) => {
+ console.error(err)
+ setErroredFetches((p) => [...p, 'tavernEvents'])
+ })
+
+ getMyTavernLocation()
+ .then(setSelectedTavern)
+ .catch((err: Error) => {
+ console.error(err)
+ setErroredFetches((p) => [...p, 'myTavernLocation'])
+ })
+
+ getTavernPeople()
+ .then(setTavernPeople)
+ .catch((err: Error) => {
+ console.error(err)
+ setErroredFetches((p) => [...p, 'tavernPeople'])
+ })
+
+ getShirtSize()
+ .then(setShirtSize)
+ .catch((err: Error) => {
+ console.error(err)
+ setErroredFetches((p) => [...p, 'shirtSize'])
+ })
}, [])
const handleTavernSelect = (tavernId: string | null) => {
@@ -262,8 +445,14 @@ export default function Tavern() {
{selectedTavern?.eventDate ? (
@@ -289,11 +478,27 @@ export default function Tavern() {
) : null}
-
+ {erroredFetches.includes('tavernEvents') ? (
+
+ Failed to load tavern events for the tavern map.
+
+ ) : erroredFetches.includes('myTavernLocation') ? (
+
+ Failed to load your chosen tavern location for the tavern map.
+
+ ) : erroredFetches.includes('tavernPeople') ? (
+
+ Failed to load tavern people for the tavern map.
+
+ ) : !tavernEvents || !tavernPeople ? (
+ Loading tavern map...
+ ) : (
+
+ )}
)
diff --git a/src/app/utils/tavern.ts b/src/app/utils/tavern.ts
index 1a607e3f..f33227bb 100644
--- a/src/app/utils/tavern.ts
+++ b/src/app/utils/tavern.ts
@@ -9,7 +9,7 @@ Airtable.configure({
endpointUrl: process.env.AIRTABLE_ENDPOINT_URL,
})
-type RsvpStatus = 'none' | 'organizer' | 'participant'
+export type RsvpStatus = 'none' | 'organizer' | 'participant'
export const setTavernRsvpStatus = async (rsvpStatus: RsvpStatus) => {
// check auth
const session = await getSession()