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

disabled switch to change from free to paid event if an event has reg… #910

Merged
merged 14 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 9 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: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
### 🎨 - Designendringer

## Neste versjon

- 🦟 **Vipps betaling**. Diverse bugs i betalingsløsningen er nå fikset.
- ✨ **Bannere**. Tidsbegrensede bannere kan nå opprettes.

## versjon 2023.24.09
Expand Down
4 changes: 4 additions & 0 deletions src/api/api.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export const STRIKES_ENDPOINT = 'strikes';
export const SUBMISSIONS_ENDPOINT = 'submissions';
export const USERS_ENDPOINT = 'users';
export const WARNINGS_ENDPOINT = 'warnings';
export const PAYMENT_ENDPOINT = 'payments';

export default {
// Auth
Expand Down Expand Up @@ -161,6 +162,9 @@ export default {
deleteRegistration: (eventId: Event['id'], userId: User['user_id']) =>
IFetch<RequestResponse>({ method: 'DELETE', url: `${EVENTS_ENDPOINT}/${String(eventId)}/${EVENT_REGISTRATIONS_ENDPOINT}/${userId}/` }),

// Payments
createPaymentOrder: (item: Partial<Order>) => IFetch<Order>({ method: 'POST', url: `${PAYMENT_ENDPOINT}/`, data: item }),

// Forms
getForm: (formId: string) => IFetch<Form>({ method: 'GET', url: `${FORMS_ENDPOINT}/${formId}/` }),
getFormTemplates: () => IFetch<Array<Form>>({ method: 'GET', url: `${FORMS_ENDPOINT}/` }),
Expand Down
16 changes: 16 additions & 0 deletions src/hooks/Payment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useMutation, UseMutationResult, useQueryClient } from 'react-query';

import { Order, RequestResponse } from 'types';

import API from 'api/api';

export const ORDER_QUERY_KEYS = 'payment';

export const useCreatePaymentOrder = (): UseMutationResult<Partial<Order>, RequestResponse, Partial<Order>, unknown> => {
const queryClient = useQueryClient();
return useMutation((item) => API.createPaymentOrder(item), {
onSuccess: () => {
queryClient.invalidateQueries(ORDER_QUERY_KEYS);
},
});
};
1 change: 1 addition & 0 deletions src/pages/EventAdministration/components/EventEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ const EventEditor = ({ eventId, goToEvent }: EventEditorProps) => {
</Row>
<Bool
control={control}
disabled={Boolean(data?.list_count && data?.list_count > 0)}
formState={formState}
label={
<>
Expand Down
44 changes: 33 additions & 11 deletions src/pages/EventDetails/components/CountdownTimer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import styled from '@emotion/styled';
import { Box, Typography } from '@mui/material';
import { Box, Button, CircularProgress, Typography } from '@mui/material';
import { differenceInMilliseconds, formatDistanceStrict } from 'date-fns';
import { nb } from 'date-fns/locale';
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';

import { Event, Order } from 'types';

import { useCreatePaymentOrder } from 'hooks/Payment';
import { useSnackbar } from 'hooks/Snackbar';

import Paper from 'components/layout/Paper';

Expand Down Expand Up @@ -37,17 +41,19 @@ const convertTime = (milliseconds?: number) => {
});
};

type Order = {
expire_date: Date;
payment_link?: string;
type Registration = {
payment_expiredate: Date;
event_id: Event['id'];
};

const CountdownTimer = ({ payment_link, expire_date }: Order) => {
const [timeLeft, setTimeLeft] = useState(convertTime(getTimeDifference(expire_date)));
const CountdownTimer = ({ payment_expiredate, event_id }: Registration) => {
const [timeLeft, setTimeLeft] = useState(convertTime(getTimeDifference(payment_expiredate)));
const createPaymentOrder = useCreatePaymentOrder();
const showSnackbar = useSnackbar();

useEffect(() => {
const interval = setInterval(() => {
const distance = getTimeDifference(expire_date);
const distance = getTimeDifference(payment_expiredate);

if (distance && distance > 0) {
setTimeLeft(convertTime(distance));
Expand All @@ -61,12 +67,28 @@ const CountdownTimer = ({ payment_link, expire_date }: Order) => {
};
}, []);

const create = (data: Partial<Order>) => {
createPaymentOrder.mutate(data, {
onSuccess: (data) => {
const payment_link = data.payment_link;
window.location.replace(payment_link || '');
},
onError: () => {
showSnackbar('Det skjedde en feil med oppretting betalingsordre.', 'error');
},
});
};

if (new Date(payment_expiredate) <= new Date()) {
return null;
}

return (
<ContentPaper>
<Box sx={{ textAlign: 'center', p: 2 }}>
<Link to={payment_link || '/'}>
<img alt='Betal med vipps' src={VIPPS} />
</Link>
<Button disabled={createPaymentOrder.isLoading} onClick={() => create({ event: event_id })}>
{createPaymentOrder.isLoading ? <CircularProgress /> : <img alt='Betal med vipps' src={VIPPS} />}
</Button>
</Box>
<Typography align='center' sx={{ color: (theme) => theme.palette.text.primary }}>
Betal innen {timeLeft} for å beholde plassen på arrangementet.
Expand Down
12 changes: 8 additions & 4 deletions src/pages/EventDetails/components/EventRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,12 @@ const EventRenderer = ({ data, preview = false }: EventRendererProps) => {
if (user) {
deleteRegistration.mutate(user.user_id, {
onSuccess: (response) => {
showSnackbar(response.detail, 'success');
event('unregistered', 'event-registration', `Unregistered for event: ${data.title}`);
if (registration?.has_paid_order) {
showSnackbar('Du har blitt meldt av arrangementet, og vil få refundert pengene innen kort tid', 'success');
} else {
showSnackbar(response.detail, 'success');
event('unregistered', 'event-registration', `Unregistered for event: ${data.title}`);
}
},
onError: (e) => {
showSnackbar(e.detail, 'error');
Expand Down Expand Up @@ -438,8 +442,8 @@ const EventRenderer = ({ data, preview = false }: EventRendererProps) => {
<Stack gap={1} sx={{ width: '100%' }}>
<AspectRatioImg alt={data.image_alt || data.title} borderRadius src={data.image} />
{lgDown && <Info />}
{registration && data.paid_information && !registration.has_paid_order && (
<CountdownTimer expire_date={registration.order.expire_date} payment_link={registration.order.payment_link} />
{registration && data.paid_information && !registration.has_paid_order && !registration.is_on_wait && (
<CountdownTimer event_id={data.id} payment_expiredate={registration.payment_expiredate} />
)}
<ContentPaper>
<Typography gutterBottom sx={{ color: (theme) => theme.palette.text.primary, fontSize: '2.4rem', wordWrap: 'break-word' }} variant='h1'>
Expand Down
4 changes: 1 addition & 3 deletions src/types/Event.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { BaseGroup, Group } from 'types/Group';
import { Permissions } from 'types/Misc';
import { User, UserList } from 'types/User';

import { Order } from './Order';

export type Category = {
created_at: string;
id: number;
Expand Down Expand Up @@ -84,7 +82,7 @@ export type Registration = {
survey_submission: UserSubmission;
has_unanswered_evaluation: boolean;
user_info: UserList;
order: Order;
payment_expiredate: Date;
has_paid_order?: boolean;
};

Expand Down
4 changes: 1 addition & 3 deletions src/types/Order.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ import { Event } from 'types/Event';
import { User } from 'types/User';

export type Order = {
access: string[];
order_id: string;
user_id: User['user_id'];
event_id: Event['id'];
event: Event['id'];
status: string;
expire_date: Date;
payment_link: string;
};
Loading