Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ run_all:
run:
cd server/src && go install # Install first so that we keep cached build objects around.

set -a && . server/debug.env && set +a && \
set -a && \
. server/debug.env && \
{ [ -f .env ] && . ./.env || true; } && \
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should launch.json be updated too? 🙏:)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left this one: the Go Server debug config loads a single envFile (server/debug.env), and the new .env is optional (only needed for the Places key locally). Pointing the debugger at a .env most people won't have would break 'Go Server' for them. If you want Places in the debugger, easiest is to drop GOOGLE_PLACES_API_KEY into your local server/debug.env. I documented the .env route in the README.

(posted by claude)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so far makefile and launch.json behavior have been kept in sync and i'd like to keep it that way if possible, so we don't have situations where things work depending on how they're launched. perhaps we could have 'make deps' create the file if it's missing so it can be added to launch.json too?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you say how to populate .env in the README, or make a template env file and just mention it in the README? probably say this somewhere: "This API key can be found in GCP under the dev environment."

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — added a note under the Google Places section of the README on populating a root .env, including that the key is in GCP under the dev environment.

(posted by claude)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that actually where the key you used is? I tried it and got this error:

Google Maps JavaScript API error: ApiNotActivatedMapError
https://developers.google.com/maps/documentation/javascript/error-messages#api-not-activated-map-error

Would be great to mention which project/key in the readme. I'd like to test it out so pls lmk :)

set +a && \
cd server/src && \
PORT=$(PORT) go run main.go

Expand Down
4 changes: 3 additions & 1 deletion cli/cmd/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ INSERT INTO activists
VALUES
(`+ch+`, 1000, 'nnn', 'test2@gmail.com', '', 'United States', 'Supporter', 'Petition: no-more-bad-things', '`+currentDateString(1)+`');

INSERT INTO events VALUES
INSERT INTO events
(id, name, date, event_type, survey_sent, suppress_survey, circle_id, chapter_id)
VALUES
%s

INSERT INTO event_attendance (activist_id, event_id) VALUES
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
'use client'

import { useRouter } from 'next/navigation'
import { useQuery } from '@tanstack/react-query'
import { format, parseISO } from 'date-fns'
import {
CheckCircle2,
Users,
Pencil,
CalendarPlus,
Home,
Clock,
MapPin,
Globe,
} from 'lucide-react'
import { API_PATH, apiClient } from '@/lib/api'
import { Button } from '@/components/ui/button'
import { formatEventTimeRange } from '@/lib/timezone'

export function EventConfirmation({ eventId }: { eventId: number }) {
const router = useRouter()

// Hydrated by the server page (same query key as the event form), so this
// resolves immediately on first render.
const { data: event } = useQuery({
queryKey: [API_PATH.EVENT_GET, String(eventId)],
queryFn: ({ signal }) => apiClient.getEvent(eventId, signal),
})

const timeRange = event
? formatEventTimeRange(
event.event_date,
event.start_time ?? '',
event.end_time ?? '',
event.timezone ?? '',
)
: ''
const locationLabel =
event?.location?.name || event?.location?.formatted_address

return (
<div className="flex flex-col gap-6">
<div className="flex flex-col items-center gap-3 text-center">
<CheckCircle2 className="h-12 w-12 text-green-600" />
<div>
<h2 className="text-xl font-semibold">Event created</h2>
<p className="mt-1 text-sm text-muted-foreground">
Your event is scheduled. Take attendance when the event happens.
Comment thread
alexsapps marked this conversation as resolved.
Outdated
</p>
</div>
</div>

{event && (
<div className="rounded-xl border bg-card p-5 shadow-sm">
<p className="text-base font-semibold">{event.event_name}</p>
<div className="mt-2 flex flex-wrap items-center gap-x-3 gap-y-1.5 text-sm text-muted-foreground">
<span className="inline-flex items-center rounded-full bg-muted px-2 py-0.5 text-xs font-medium">
{event.event_type}
</span>
<span>{format(parseISO(event.event_date), 'PPP')}</span>
{timeRange && (
<span className="inline-flex items-center gap-1">
<Clock className="h-3.5 w-3.5" />
{timeRange}
</span>
)}
{event.is_online ? (
<span className="inline-flex items-center gap-1">
<Globe className="h-3.5 w-3.5" />
Online
</span>
) : (
locationLabel && (
<span className="inline-flex items-center gap-1">
<MapPin className="h-3.5 w-3.5" />
{locationLabel}
</span>
)
)}
</div>
</div>
)}

<div className="flex flex-col gap-2">
<Button type="button" onClick={() => router.push(`/events/${eventId}`)}>
<Users className="h-4 w-4" />
Take attendance now
</Button>
<Button
type="button"
variant="outline"
onClick={() => router.push(`/events/${eventId}?edit=1`)}
>
<Pencil className="h-4 w-4" />
Edit event
</Button>
<Button
type="button"
variant="outline"
onClick={() => router.push('/events/new')}
>
<CalendarPlus className="h-4 w-4" />
Create another event
</Button>
<Button
type="button"
variant="ghost"
onClick={() => router.push('/home')}
>
<Home className="h-4 w-4" />
Done
</Button>
</div>
</div>
)
}
45 changes: 45 additions & 0 deletions frontend-v2/src/app/(authed)/events/[id]/confirmation/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
dehydrate,
HydrationBoundary,
QueryClient,
} from '@tanstack/react-query'
import { notFound } from 'next/navigation'
import { ContentWrapper } from '@/app/content-wrapper'
import { EventConfirmation } from './event-confirmation'
import { API_PATH, ApiClient } from '@/lib/api'
import { getCookies } from '@/lib/auth'
import { redirectForHttpError } from '@/lib/server-auth'

// Shown right after a scheduled (public) event is created. Attendance happens
// later, at the event, so we confirm the event is on the schedule and offer the
// natural next steps instead of dropping the user on the attendance page.
export default async function EventConfirmationPage({
params,
}: {
params: Promise<{ id: string }>
}) {
const { id } = await params
const eventId = parseInt(id)
if (Number.isNaN(eventId)) {
notFound()
}

const apiClient = new ApiClient(await getCookies())
const queryClient = new QueryClient()

await redirectForHttpError(() =>
// Intentionally use fetchQuery instead of prefetchQuery; see redirectForHttpError for details.
queryClient.fetchQuery({
queryKey: [API_PATH.EVENT_GET, String(eventId)],
queryFn: ({ signal }) => apiClient.getEvent(eventId, signal),
}),
)

return (
<ContentWrapper size="sm" className="gap-8">
<HydrationBoundary state={dehydrate(queryClient)}>
<EventConfirmation eventId={eventId} />
</HydrationBoundary>
</ContentWrapper>
)
}
7 changes: 5 additions & 2 deletions frontend-v2/src/app/(authed)/events/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ import { redirectForHttpError } from '@/lib/server-auth'

export default async function EditEventPage({
params,
searchParams,
}: {
params: Promise<{ id: string }>
searchParams: Promise<{ edit?: string }>
}) {
const { id } = await params
const { edit } = await searchParams
const eventId = parseInt(id)
if (Number.isNaN(eventId)) {
notFound()
Expand All @@ -35,8 +38,8 @@ export default async function EditEventPage({
return (
<ContentWrapper size="sm" className="gap-8">
<HydrationBoundary state={dehydrate(queryClient)}>
<h1 className="text-3xl font-bold">Attendance</h1>
<EventForm mode="event" />
<h1 className="text-3xl font-bold">Event</h1>
<EventForm mode="event" startExpanded={edit === '1'} />
Comment thread
alexsapps marked this conversation as resolved.
Outdated
</HydrationBoundary>
</ContentWrapper>
)
Expand Down
Loading
Loading