Skip to content

Commit 5cf2c32

Browse files
authored
Refactor events section in user dashboard (#543)
Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com>
1 parent f24f946 commit 5cf2c32

7 files changed

Lines changed: 244 additions & 324 deletions

File tree

database/migrations/functions/dashboard-user/list_user_events.sql

Lines changed: 91 additions & 219 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,40 @@
22
create or replace function list_user_events(p_user_id uuid, p_filters jsonb)
33
returns json as $$
44
with
5-
-- Parse pagination filters.
6-
filters as (
7-
select
8-
(p_filters->>'limit')::int as limit_value,
9-
(p_filters->>'offset')::int as offset_value
10-
),
11-
-- Collect attendee events.
12-
attendee_events as (
5+
-- Collect visible upcoming events once for all participation roles.
6+
visible_events as (
137
select
8+
g.community_id,
149
e.event_id,
1510
e.group_id,
16-
e.starts_at,
17-
g.community_id,
18-
ea.registration_answers,
11+
e.starts_at
12+
from event e
13+
join "group" g using (group_id)
14+
where e.canceled = false
15+
and e.deleted = false
16+
and e.published = true
17+
and e.starts_at > now()
18+
and g.active = true
19+
and g.deleted = false
20+
),
21+
-- Collect user participation roles.
22+
role_rows as (
23+
-- Attendee
24+
select
1925
case
2026
when ea.status = 'registration-questions-pending'
21-
and pending_purchase.event_purchase_id is not null then 'Payment pending'
22-
when ea.status = 'registration-questions-pending' then 'Registration pending'
23-
else 'Attendee'
24-
end as role,
25-
ea.status = 'registration-questions-pending'
26-
and pending_purchase.event_purchase_id is not null as pending_payment,
27-
ea.status = 'registration-questions-pending'
28-
and pending_purchase.event_purchase_id is null as registration_questions_pending,
27+
and pending_purchase.event_purchase_id is not null then 'pending-payment'
28+
when ea.status = 'registration-questions-pending' then 'registration-questions-pending'
29+
else 'attendee'
30+
end as attendance_status,
31+
ea.event_id,
32+
ea.registration_answers,
33+
'attendee'::text as role,
2934
case
3035
when ea.status = 'registration-questions-pending' then pending_purchase.provider_checkout_url
3136
else null
3237
end as resume_checkout_url
3338
from event_attendee ea
34-
join event e using (event_id)
35-
join "group" g using (group_id)
3639
left join lateral (
3740
select
3841
ep.event_purchase_id,
@@ -47,251 +50,120 @@ returns json as $$
4750
) pending_purchase on true
4851
where ea.user_id = p_user_id
4952
and ea.status in ('confirmed', 'registration-questions-pending')
50-
and e.canceled = false
51-
and e.deleted = false
52-
and e.published = true
53-
and e.starts_at > now()
54-
and g.active = true
55-
and g.deleted = false
56-
),
57-
-- Collect host events.
58-
host_events as (
53+
54+
union all
55+
56+
-- Host
5957
select
60-
e.event_id,
61-
e.group_id,
62-
e.starts_at,
63-
g.community_id,
58+
null::text as attendance_status,
59+
eh.event_id,
6460
null::jsonb as registration_answers,
65-
'Host'::text as role,
66-
false as pending_payment,
67-
false as registration_questions_pending,
61+
'host'::text as role,
6862
null::text as resume_checkout_url
6963
from event_host eh
70-
join event e using (event_id)
71-
join "group" g using (group_id)
7264
where eh.user_id = p_user_id
73-
and e.canceled = false
74-
and e.deleted = false
75-
and e.published = true
76-
and e.starts_at > now()
77-
and g.active = true
78-
and g.deleted = false
79-
),
80-
-- Collect event-level speaker events.
81-
event_speaker_events as (
65+
66+
union all
67+
68+
-- Event speaker
8269
select
83-
e.event_id,
84-
e.group_id,
85-
e.starts_at,
86-
g.community_id,
70+
null::text as attendance_status,
71+
es.event_id,
8772
null::jsonb as registration_answers,
88-
'Speaker'::text as role,
89-
false as pending_payment,
90-
false as registration_questions_pending,
73+
'speaker'::text as role,
9174
null::text as resume_checkout_url
9275
from event_speaker es
93-
join event e using (event_id)
94-
join "group" g using (group_id)
9576
where es.user_id = p_user_id
96-
and e.canceled = false
97-
and e.deleted = false
98-
and e.published = true
99-
and e.starts_at > now()
100-
and g.active = true
101-
and g.deleted = false
102-
),
103-
-- Collect session-level speaker events.
104-
session_speaker_events as (
77+
78+
union all
79+
80+
-- Session speaker
10581
select
106-
e.event_id,
107-
e.group_id,
108-
e.starts_at,
109-
g.community_id,
82+
null::text as attendance_status,
83+
s.event_id,
11084
null::jsonb as registration_answers,
111-
'Speaker'::text as role,
112-
false as pending_payment,
113-
false as registration_questions_pending,
85+
'speaker'::text as role,
11486
null::text as resume_checkout_url
11587
from session_speaker ss
11688
join session s using (session_id)
117-
join event e using (event_id)
118-
join "group" g using (group_id)
11989
where ss.user_id = p_user_id
120-
and e.canceled = false
121-
and e.deleted = false
122-
and e.published = true
123-
and e.starts_at > now()
124-
and g.active = true
125-
and g.deleted = false
126-
),
127-
-- Combine all user roles by event.
128-
participant_roles as (
129-
select
130-
community_id,
131-
event_id,
132-
group_id,
133-
pending_payment,
134-
registration_answers,
135-
registration_questions_pending,
136-
resume_checkout_url,
137-
role,
138-
starts_at
139-
from attendee_events
140-
union all
141-
select
142-
community_id,
143-
event_id,
144-
group_id,
145-
pending_payment,
146-
registration_answers,
147-
registration_questions_pending,
148-
resume_checkout_url,
149-
role,
150-
starts_at
151-
from host_events
152-
union all
153-
select
154-
community_id,
155-
event_id,
156-
group_id,
157-
pending_payment,
158-
registration_answers,
159-
registration_questions_pending,
160-
resume_checkout_url,
161-
role,
162-
starts_at
163-
from event_speaker_events
164-
union all
165-
select
166-
community_id,
167-
event_id,
168-
group_id,
169-
pending_payment,
170-
registration_answers,
171-
registration_questions_pending,
172-
resume_checkout_url,
173-
role,
174-
starts_at
175-
from session_speaker_events
176-
),
177-
-- Deduplicate role rows for the same event.
178-
unique_roles as (
179-
select distinct
180-
pr.community_id,
181-
pr.event_id,
182-
pr.group_id,
183-
pr.pending_payment,
184-
pr.registration_answers,
185-
pr.registration_questions_pending,
186-
pr.resume_checkout_url,
187-
pr.starts_at,
188-
pr.role
189-
from participant_roles pr
19090
),
19191
-- Aggregate roles per event.
19292
event_rows as (
19393
select
194-
ur.community_id,
195-
ur.event_id,
196-
ur.group_id,
197-
bool_or(ur.pending_payment) as pending_payment,
198-
(max(ur.registration_answers::text) filter (where ur.registration_answers is not null))::jsonb
94+
max(rr.attendance_status) as attendance_status,
95+
ve.community_id,
96+
ve.event_id,
97+
ve.group_id,
98+
(max(rr.registration_answers::text) filter (where rr.registration_answers is not null))::jsonb
19999
as registration_answers,
200-
bool_or(ur.registration_questions_pending) as registration_questions_pending,
201-
max(ur.resume_checkout_url) as resume_checkout_url,
202-
array_agg(ur.role order by ur.role asc) as roles,
203-
ur.starts_at
204-
from unique_roles ur
205-
group by ur.community_id, ur.event_id, ur.group_id, ur.starts_at
100+
max(rr.resume_checkout_url) as resume_checkout_url,
101+
array_agg(distinct rr.role order by rr.role asc) as roles,
102+
ve.starts_at
103+
from visible_events ve
104+
join role_rows rr using (event_id)
105+
group by ve.community_id, ve.event_id, ve.group_id, ve.starts_at
206106
),
207107
-- Select the requested page.
208108
event_rows_page as (
209109
select
110+
er.attendance_status,
210111
er.community_id,
211112
er.event_id,
212113
er.group_id,
213-
er.pending_payment,
214114
er.registration_answers,
215-
er.registration_questions_pending,
216115
er.resume_checkout_url,
217116
er.roles,
218117
er.starts_at
219118
from event_rows er
220119
order by er.starts_at asc, er.event_id asc
221-
offset (select offset_value from filters)
222-
limit (select limit_value from filters)
223-
),
224-
-- Count total events before pagination.
225-
totals as (
226-
select count(*)::int as total
227-
from event_rows
228-
),
229-
-- Render paginated events to JSON.
230-
events_json as (
120+
offset (p_filters->>'offset')::int
121+
limit (p_filters->>'limit')::int
122+
)
123+
-- Build final payload.
124+
select json_build_object(
125+
'events',
126+
(
231127
select coalesce(
232128
json_agg(
233129
json_build_object(
234-
'can_cancel_attendance',
235-
event_rows_page.roles = array['Attendee'::text]
236-
and event_rows_page.registration_questions_pending = false
237-
and not exists (
130+
'event',
131+
get_event_summary(
132+
erp.community_id,
133+
erp.group_id,
134+
erp.event_id
135+
),
136+
'has_paid_purchase',
137+
exists (
238138
select 1
239139
from event_purchase ep
240-
where ep.event_id = event_rows_page.event_id
140+
where ep.event_id = erp.event_id
241141
and ep.user_id = p_user_id
242142
and ep.status in ('completed', 'refund-requested')
243143
and ep.amount_minor > 0
244144
),
245-
'can_complete_registration_questions',
246-
event_rows_page.pending_payment = false
247-
and (
248-
event_rows_page.registration_questions_pending
249-
or (
250-
'Attendee' = any(event_rows_page.roles)
251-
and
252-
json_array_length(
253-
get_event_registration_questions(
254-
event_rows_page.community_id,
255-
event_rows_page.event_id
256-
)
257-
) > 0
258-
and event_rows_page.starts_at > now()
259-
)
260-
),
261-
'event',
262-
get_event_summary(
263-
event_rows_page.community_id,
264-
event_rows_page.group_id,
265-
event_rows_page.event_id
266-
),
267-
'pending_payment',
268-
event_rows_page.pending_payment,
269-
'registration_answers',
270-
event_rows_page.registration_answers,
271145
'registration_questions',
272-
get_event_registration_questions(
273-
event_rows_page.community_id,
274-
event_rows_page.event_id
275-
),
276-
'registration_questions_pending',
277-
event_rows_page.registration_questions_pending,
278-
'resume_checkout_url',
279-
event_rows_page.resume_checkout_url,
146+
rq.registration_questions,
280147
'roles',
281-
event_rows_page.roles
148+
erp.roles,
149+
'attendance_status',
150+
erp.attendance_status,
151+
'registration_answers',
152+
erp.registration_answers,
153+
'resume_checkout_url',
154+
erp.resume_checkout_url
282155
)
283-
order by event_rows_page.starts_at asc, event_rows_page.event_id asc
156+
order by erp.starts_at asc, erp.event_id asc
284157
),
285158
'[]'::json
286-
) as events
287-
from event_rows_page
288-
)
289-
-- Build final payload.
290-
select json_build_object(
291-
'events',
292-
events_json.events,
159+
)
160+
from event_rows_page erp
161+
cross join lateral (
162+
select get_event_registration_questions(erp.community_id, erp.event_id)
163+
as registration_questions
164+
) rq
165+
),
293166
'total',
294-
totals.total
295-
)
296-
from events_json, totals;
167+
(select count(*)::int from event_rows)
168+
);
297169
$$ language sql;

0 commit comments

Comments
 (0)