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

Use a Context for fetching Registrations #10323

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
26 changes: 13 additions & 13 deletions app/webpacker/components/RegistrationsV2/Register/CompetingStep.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { events } from '../../../lib/wca-data.js.erb';
import { eventsNotQualifiedFor, isQualifiedForEvent } from '../../../lib/helpers/qualifications';
import { eventQualificationToString } from '../../../lib/utils/wcif';
import { hasNotPassed } from '../../../lib/utils/dates';
import { useRegistration } from '../lib/RegistrationProvider';

const maxCommentLength = 240;

Expand All @@ -50,13 +51,12 @@ export default function CompetingStep({
competitionInfo,
user,
preferredEvents,
registration,
refetchRegistration,
qualifications,
}) {
const maxEvents = competitionInfo.events_per_registration_limit ?? Infinity;
const isRegistered = Boolean(registration);
const hasPaid = registration?.payment?.has_paid;
const {
registration, isRegistered, hasPaid, isPolling, isProcessing, startPolling, refetchRegistration,
} = useRegistration();
const dispatch = useDispatch();

const confirm = useConfirm();
Expand All @@ -78,8 +78,6 @@ export default function CompetingStep({
const [hasInteracted, setHasInteracted] = useState(false);
const [guests, setGuests] = useState(0);

const [processing, setProcessing] = useState(false);

useEffect(() => {
if (isRegistered && registration.competing.registration_status !== 'cancelled') {
setComment(registration.competing.comment ?? '');
Expand All @@ -88,6 +86,13 @@ export default function CompetingStep({
}
}, [isRegistered, registration]);

useEffect(() => {
if (isPolling && !isProcessing) {
refetchRegistration();
nextStep();
}
}, [isPolling, isProcessing, nextStep, refetchRegistration]);

const queryClient = useQueryClient();
const { mutate: updateRegistrationMutation, isPending: isUpdating } = useMutation({
mutationFn: updateRegistration,
Expand Down Expand Up @@ -130,7 +135,7 @@ export default function CompetingStep({
// We can't update the registration yet, because there might be more steps needed
// And the Registration might still be processing
dispatch(setMessage('registrations.flash.registered', 'positive'));
setProcessing(true);
startPolling();
},
});

Expand Down Expand Up @@ -266,15 +271,10 @@ export default function CompetingStep({
const formWarnings = useMemo(() => potentialWarnings(competitionInfo), [competitionInfo]);
return (
<Segment basic loading={isUpdating}>
{processing && (
{isPolling && (
<Processing
competitionInfo={competitionInfo}
user={user}
onProcessingComplete={async () => {
setProcessing(false);
await refetchRegistration();
nextStep();
}}
/>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,23 @@ import Loading from '../../Requests/Loading';
import i18n from '../../../lib/i18n';
import useCheckboxState from '../../../lib/hooks/useCheckboxState';
import AutonumericField from '../../wca/FormBuilder/input/AutonumericField';
import getPaymentTicket from "../api/payment/get/getPaymentTicket";
import getPaymentTicket from '../api/payment/get/getPaymentTicket';
import { useRegistration } from '../lib/RegistrationProvider';

export default function PaymentStep({
competitionInfo,
setDonationAmount,
donationAmount,
displayAmount,
registration,
nextStep,
conversionFetching,
}) {
const stripe = useStripe();
const elements = useElements();
const dispatch = useDispatch();

const { registration } = useRegistration();

const [isLoading, setIsLoading] = useState(false);
const [isDonationChecked, setDonationChecked] = useCheckboxState(false);

Expand Down
32 changes: 7 additions & 25 deletions app/webpacker/components/RegistrationsV2/Register/Processing.jsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,13 @@
import { useQuery } from '@tanstack/react-query';
import React, { useEffect, useState } from 'react';
import React from 'react';
import { Message, Modal } from 'semantic-ui-react';
import I18n from '../../../lib/i18n';
import pollRegistrations from '../api/registration/get/poll_registrations';
import { useRegistration } from '../lib/RegistrationProvider';

const REFETCH_INTERVAL = 3000;
export default function Processing() {
const { pollCounter, queueCount } = useRegistration();

export default function Processing({ competitionInfo, user, onProcessingComplete }) {
const [pollCounter, setPollCounter] = useState(0);

const { data } = useQuery({
queryKey: ['registration-status-polling', user.id, competitionInfo.id],
queryFn: async () => pollRegistrations(user.id, competitionInfo),
refetchInterval: REFETCH_INTERVAL,
onSuccess: () => {
setPollCounter(pollCounter + 1);
},
});
useEffect(() => {
const processingComplete = competitionInfo.registration_version === 'v2' ? data?.status?.competing === 'pending'
: data && !data.processing;
if (processingComplete) {
onProcessingComplete();
}
}, [competitionInfo.registration_version, data, onProcessingComplete]);
return (
<Modal open={data?.status?.competing !== 'pending' || !data?.processing} dimmer="blurring">
<Modal open dimmer="blurring">
<Modal.Header>
{I18n.t('competitions.registration_v2.register.processing')}
</Modal.Header>
Expand All @@ -35,10 +17,10 @@ export default function Processing({ competitionInfo, user, onProcessingComplete
{I18n.t('competitions.registration_v2.register.processing_longer')}
</Message>
)}
{data && data.queue_count > 0 && (
{queueCount > 0 && (
<Message warning>
{I18n.t('competitions.registration_v2.register.processing_queue', {
queueCount: data.queue_count,
queueCount,
})}
</Message>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ import { useDispatch } from '../../../lib/providers/StoreProvider';
import { useConfirm } from '../../../lib/providers/ConfirmProvider';
import { contactCompetitionUrl } from '../../../lib/requests/routes.js.erb';
import RegistrationStatus from './RegistrationStatus';
import { useRegistration } from '../lib/RegistrationProvider';

export default function RegistrationOverview({
nextStep, registration, competitionInfo,
nextStep, competitionInfo,
}) {
const dispatch = useDispatch();
const confirm = useConfirm();
const { registration, isRejected, isAccepted } = useRegistration();

const hasRegistrationEditDeadlinePassed = hasPassed(
competitionInfo.event_change_deadline_date ?? competitionInfo.start_date,
);

const isRejected = registration.competing.registration_status === 'rejected';

const deleteAllowed = (registration.competing.registration_status !== 'accepted'
|| competitionInfo.allow_registration_self_delete_after_acceptance);
const deleteAllowed = (!isAccepted
|| competitionInfo.allow_registration_self_delete_after_acceptance);

const queryClient = useQueryClient();

Expand Down
13 changes: 5 additions & 8 deletions app/webpacker/components/RegistrationsV2/Register/StepPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import RegistrationRequirements from './RegistrationRequirements';
import StripeWrapper from './StripeWrapper';
import i18n from '../../../lib/i18n';
import RegistrationOverview from './RegistrationOverview';
import { useRegistration } from '../lib/RegistrationProvider';

const requirementsStepConfig = {
key: 'requirements',
Expand Down Expand Up @@ -65,16 +66,14 @@ export default function StepPanel({
competitionInfo,
preferredEvents,
user,
registration,
refetchRegistration,
stripePublishableKey,
connectedAccountId,
qualifications,
}) {
const isRegistered = Boolean(registration) && registration.competing.registration_status !== 'cancelled';
const isAccepted = isRegistered && registration.competing.registration_status === 'accepted';
const isRejected = isRegistered && registration.competing.registration_status === 'rejected';
const hasPaid = registration?.payment?.has_paid;
const {
isRegistered, isAccepted, isRejected, hasPaid,
} = useRegistration();

const registrationFinished = (isRegistered && hasPaid) || (isRegistered && !competitionInfo['using_payment_integrations?']);

const steps = useMemo(() => {
Expand Down Expand Up @@ -135,8 +134,6 @@ export default function StepPanel({
))}
</Step.Group>
<CurrentStepPanel
registration={registration}
refetchRegistration={refetchRegistration}
competitionInfo={competitionInfo}
preferredEvents={preferredEvents}
user={user}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useQuery } from '@tanstack/react-query';
import PaymentStep from './PaymentStep';
import { fetchJsonOrError } from '../../../lib/requests/fetchWithAuthenticityToken';
import { paymentDenominationUrl } from '../../../lib/requests/routes.js.erb';
import { useRegistration } from '../lib/RegistrationProvider';

const convertISOAmount = async (amount, currency) => {
const { data } = await fetchJsonOrError(
Expand All @@ -20,13 +21,14 @@ export default function StripeWrapper({
stripePublishableKey,
connectedAccountId,
user,
registration,
nextStep,
}) {
const [stripePromise, setStripePromise] = useState(null);
const initialAmount = competitionInfo.base_entry_fee_lowest_denomination;
const [donationAmount, setDonationAmount] = useState(0);

const { registration } = useRegistration();

const {
data, isFetching,
} = useQuery({
Expand Down
48 changes: 16 additions & 32 deletions app/webpacker/components/RegistrationsV2/Register/index.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import React, { useCallback, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import StepPanel from './StepPanel';
import { getSingleRegistration } from '../api/registration/get/get_registrations';
import Loading from '../../Requests/Loading';
import RegistrationMessage, { setMessage } from './RegistrationMessage';
import StoreProvider, { useDispatch } from '../../../lib/providers/StoreProvider';
import RegistrationMessage from './RegistrationMessage';
import StoreProvider from '../../../lib/providers/StoreProvider';
import messageReducer from '../reducers/messageReducer';
import WCAQueryClientProvider from '../../../lib/providers/WCAQueryClientProvider';
import ConfirmProvider from '../../../lib/providers/ConfirmProvider';
import RegistrationClosedMessage from './RegistrationClosedMessage';
import RegistrationProvider, { useRegistration } from '../lib/RegistrationProvider';

export default function Index({
competitionInfo,
Expand All @@ -23,15 +22,17 @@ export default function Index({
<WCAQueryClientProvider>
<StoreProvider reducer={messageReducer} initialState={{ message: null }}>
<ConfirmProvider>
<Register
competitionInfo={competitionInfo}
userInfo={userInfo}
userCanPreRegister={userCanPreRegister}
preferredEvents={preferredEvents}
stripePublishableKey={stripePublishableKey}
connectedAccountId={connectedAccountId}
qualifications={qualifications}
/>
<RegistrationProvider competitionInfo={competitionInfo} userInfo={userInfo}>
<Register
competitionInfo={competitionInfo}
userInfo={userInfo}
userCanPreRegister={userCanPreRegister}
preferredEvents={preferredEvents}
stripePublishableKey={stripePublishableKey}
connectedAccountId={connectedAccountId}
qualifications={qualifications}
/>
</RegistrationProvider>
</ConfirmProvider>
</StoreProvider>
</WCAQueryClientProvider>
Expand All @@ -49,27 +50,12 @@ function Register({
}) {
const [timerEnded, setTimerEnded] = useState(false);

const dispatch = useDispatch();
const {
data: registration,
isFetching,
refetch,
} = useQuery({
queryKey: ['registration', competitionInfo.id, userInfo.id],
queryFn: () => getSingleRegistration(userInfo.id, competitionInfo),
onError: (data) => {
const { error } = data.json;
dispatch(setMessage(
`competitions.registration_v2.errors.${error}`,
'negative',
));
},
});

const onTimerEnd = useCallback(() => {
setTimerEnded(true);
}, [setTimerEnded]);

const { isFetching, registration } = useRegistration();

if (isFetching) {
return <Loading />;
}
Expand All @@ -82,8 +68,6 @@ function Register({
user={userInfo}
preferredEvents={preferredEvents}
competitionInfo={competitionInfo}
registration={registration}
refetchRegistration={refetch}
connectedAccountId={connectedAccountId}
stripePublishableKey={stripePublishableKey}
qualifications={qualifications}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
Message,
Segment,
} from 'semantic-ui-react';
import { getSingleRegistration } from '../api/registration/get/get_registrations';
import updateRegistration from '../api/registration/patch/update_registration';
import { useDispatch } from '../../../lib/providers/StoreProvider';
import { setMessage } from '../Register/RegistrationMessage';
Expand All @@ -25,6 +24,7 @@ import i18n from '../../../lib/i18n';
import RegistrationHistory from './RegistrationHistory';
import { hasPassed } from '../../../lib/utils/dates';
import getUsersInfo from '../api/user/post/getUserInfo';
import { useRegistration } from '../lib/RegistrationProvider';

export default function RegistrationEditor({ competitor, competitionInfo }) {
const dispatch = useDispatch();
Expand All @@ -38,14 +38,7 @@ export default function RegistrationEditor({ competitor, competitionInfo }) {

const queryClient = useQueryClient();

const { isLoading: isRegistrationLoading, data: serverRegistration, refetch } = useQuery({
queryKey: ['registration-admin', competitionInfo.id, competitor.id],
queryFn: () => getSingleRegistration(competitor.id, competitionInfo),
refetchOnWindowFocus: false,
refetchOnReconnect: false,
staleTime: Infinity,
refetchOnMount: 'always',
});
const { isFetching: isRegistrationLoading, registration: serverRegistration, refetchRegistration: refetch } = useRegistration();

const { isLoading, data: competitorsInfo } = useQuery({
queryKey: ['history-user', serverRegistration?.history],
Expand All @@ -64,7 +57,7 @@ export default function RegistrationEditor({ competitor, competitionInfo }) {
},
onSuccess: (data) => {
queryClient.setQueryData(
['registration-admin', competitionInfo.id, competitor.id],
['registration', competitionInfo.id, competitor.id],
{
...data.registration,
payment: serverRegistration.payment,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import messageReducer from '../reducers/messageReducer';
import StoreProvider from '../../../lib/providers/StoreProvider';
import WCAQueryClientProvider from '../../../lib/providers/WCAQueryClientProvider';
import ConfirmProvider from '../../../lib/providers/ConfirmProvider';
import RegistrationProvider from '../lib/RegistrationProvider';

export default function RegistrationEdit({ competitionInfo, user }) {
const ref = useRef();
Expand All @@ -14,10 +15,12 @@ export default function RegistrationEdit({ competitionInfo, user }) {
<WCAQueryClientProvider>
<StoreProvider reducer={messageReducer} initialState={{ message: null }}>
<ConfirmProvider>
<Sticky context={ref}>
<RegistrationMessage />
</Sticky>
<RegistrationEditor competitionInfo={competitionInfo} competitor={user} />
<RegistrationProvider competitionInfo={competitionInfo} userInfo={user}>
<Sticky context={ref}>
<RegistrationMessage />
</Sticky>
<RegistrationEditor competitionInfo={competitionInfo} competitor={user} />
</RegistrationProvider>
</ConfirmProvider>
</StoreProvider>
</WCAQueryClientProvider>
Expand Down
Loading
Loading