Skip to content

Commit

Permalink
Modified edit-person script to accept WCA ID via query param and sear…
Browse files Browse the repository at this point in the history
…ch option in country picker (#8975)

* Modified edit-person script to accept WCA ID via query param

* Review changes

* Search in country picker

* Review changes

* Review change
  • Loading branch information
danieljames-dj committed Mar 4, 2024
1 parent ff8b065 commit b0a7c5c
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 58 deletions.
10 changes: 7 additions & 3 deletions app/controllers/api/v0/persons_controller.rb
Expand Up @@ -16,7 +16,11 @@ def index

def show
person = Person.current.includes(:user, :ranksSingle, :ranksAverage).find_by_wca_id!(params[:wca_id])
render json: person_to_json(person)
private_attributes = []
if current_user && current_user.can_admin_results?
private_attributes = %w[incorrect_wca_id_claim_count dob]
end
render json: person_to_json(person, private_attributes)
end

def results
Expand All @@ -29,9 +33,9 @@ def competitions
render json: person.competitions
end

private def person_to_json(person)
private def person_to_json(person, private_attributes = [])
{
person: person.serializable_hash(only: [:wca_id, :name, :url, :gender, :country_iso2, :delegate_status, :teams, :avatar]),
person: person.serializable_hash(only: [:wca_id, :name, :url, :gender, :country_iso2, :delegate_status, :teams, :avatar], private_attributes: private_attributes),
competition_count: person.competitions.count,
personal_records: person.ranksSingle.each_with_object({}) do |rank_single, ranks|
event_id = rank_single.event.id
Expand Down
2 changes: 1 addition & 1 deletion app/views/mail_form/dob_contact.erb
Expand Up @@ -26,5 +26,5 @@
</tr>
</body>
</table>
<p>You can edit this person <%= link_to "here", admin_edit_person_url(person: { wca_id: @resource.wca_id }) %>.</p>
<p>You can edit this person <%= link_to "here", panel_wrt_url(wcaId: '2012JAME04', anchor: PanelController.panel_list['wrt']['editPerson']) %>.</p>
<p>A proof of identity is attached.</p>
154 changes: 101 additions & 53 deletions app/webpacker/components/Panel/Wrt/EditPerson.jsx
@@ -1,7 +1,7 @@
import React, { useState, useMemo, useEffect } from 'react';
import React, { useState, useEffect } from 'react';
import DatePicker from 'react-datepicker';
import {
Button, Form, Icon, Message,
Button, Form, Icon, Item, Message,
} from 'semantic-ui-react';
import _ from 'lodash';
import { adminCheckRecordsUrl, apiV0Urls } from '../../../lib/requests/routes.js.erb';
Expand All @@ -11,6 +11,9 @@ import Loading from '../../Requests/Loading';
import I18n from '../../../lib/i18n';
import { genders, countries } from '../../../lib/wca-data.js.erb';
import 'react-datepicker/dist/react-datepicker.css';
import useQueryParams from '../../../lib/hooks/useQueryParams';
import useLoadedData from '../../../lib/hooks/useLoadedData';
import Errored from '../../Requests/Errored';

const dateFormat = 'YYYY-MM-DD';

Expand All @@ -26,34 +29,37 @@ const countryOptions = _.map(countries.byIso2, (country) => ({
value: country.iso2,
}));

function EditPerson() {
const [person, setPerson] = useState();
function EditPersonForm({ wcaId, clearWcaId, setResponse }) {
const {
data: personFetchData, loading, error: personError,
} = useLoadedData(
apiV0Urls.persons.show(wcaId),
);
const { person } = personFetchData || {};
const [editedUserDetails, setEditedUserDetails] = useState();
const [originalUserDetails, setOriginalUserDetails] = useState();
const [incorrectClaimCount, setIncorrectClaimCount] = useState(0);
const { save, saving } = useSaveAction();
const [response, setResponse] = useState();
const wcaId = useMemo(() => person?.item?.wca_id, [person]);

useEffect(() => {
if (person) {
const userDetails = {
wcaId: person.item.wca_id,
name: person.item.name,
representing: person.item.country_iso2,
gender: person.item.gender,
dob: person.item.dob,
wcaId: person.wca_id,
name: person.name,
representing: person.country_iso2,
gender: person.gender,
dob: person.dob,
};
setOriginalUserDetails(userDetails);
setEditedUserDetails(userDetails);
setIncorrectClaimCount(person.item.incorrect_wca_id_claim_count);
setIncorrectClaimCount(person.incorrect_wca_id_claim_count);
setResponse(null);
} else {
setOriginalUserDetails(null);
setEditedUserDetails(null);
setIncorrectClaimCount(0);
}
}, [person]);
}, [person, setResponse]);

const handleFormChange = (e, { name: formName, value }) => {
setEditedUserDetails((prev) => ({ ...prev, [formName]: value }));
Expand All @@ -69,7 +75,6 @@ function EditPerson() {
showCountryChangeWarning:
originalUserDetails.representing !== editedUserDetails.representing,
});
setPerson(null);
}, {
method: 'PATCH',
}, (error) => {
Expand All @@ -83,57 +88,34 @@ function EditPerson() {
const handleDestroy = () => {
save(apiV0Urls.wrt.destroy(wcaId), {}, () => {
setResponse({ success: true });
setPerson(null);
}, { method: 'DELETE' }, (error) => setResponse({ success: false, message: `${error}` }));
};

const handleResetClaimCount = () => {
save(apiV0Urls.wrt.resetClaimCount(wcaId), {}, () => {
setResponse({ success: true, message: 'Success' });
setPerson(null);
}, { method: 'PUT' }, (error) => setResponse({ success: false, message: `${error}` }));
};

if (saving) return <Loading />;
if (loading || saving) return <Loading />;
if (personError) return <Errored />;

return (
<>
<div>
To know the difference between fix and update, refer delegate crash course&apos;s
&#34;Requesting changes to person data&#34; section.
</div>
{response != null && (
<Message
success={response.success}
error={!response.success}
content={response.message}
>
<Message.Content>
{response.success && (
<>
Success!
<br />
</>
)}
{response.showCountryChangeWarning && (
<>
The change you made may have affected national and continental records, be sure to
run
{' '}
<a href={adminCheckRecordsUrl}>check_regional_record_markers</a>
.
</>
)}
{!response.success && response.message}
</Message.Content>
</Message>
)}
<WcaSearch
value={person}
onChange={(e, { value }) => setPerson(value)}
multiple={false}
model="person"
/>
<Item>
<Item.Content>
<Item.Header>
WCA ID:
{' '}
{person.wca_id}
</Item.Header>
<Item.Description>
<Button onClick={() => clearWcaId()}>
Clear
</Button>
</Item.Description>
</Item.Content>
</Item>
<Form>
<Form.Input
label={I18n.t('activerecord.attributes.user.name')}
Expand All @@ -146,6 +128,7 @@ function EditPerson() {
options={countryOptions}
label={I18n.t('activerecord.attributes.user.country_iso2')}
name="representing"
search
disabled={!editedUserDetails}
value={editedUserDetails?.representing || ''}
onChange={handleFormChange}
Expand Down Expand Up @@ -199,4 +182,69 @@ function EditPerson() {
</>
);
}

function EditPerson() {
const [response, setResponse] = useState();
const [queryParams, updateQueryParam] = useQueryParams();
const [loading, setLoading] = useState(false);
const { wcaId } = queryParams;

if (loading) return <Loading />;

return (
<>
<div>
To know the difference between fix and update, refer delegate crash course&apos;s
&#34;Requesting changes to person data&#34; section.
</div>
{response != null && (
<Message
success={response.success}
error={!response.success}
content={response.message}
>
<Message.Content>
{response.success && (
<>
Success!
<br />
</>
)}
{response.showCountryChangeWarning && (
<>
The change you made may have affected national and continental records, be sure to
run
{' '}
<a href={adminCheckRecordsUrl}>check_regional_record_markers</a>
.
</>
)}
{!response.success && response.message}
</Message.Content>
</Message>
)}
{wcaId
? (
<EditPersonForm
wcaId={wcaId}
clearWcaId={() => {
setLoading(true);
updateQueryParam('wcaId', '');
}}
setResponse={setResponse}
/>
)
: (
<WcaSearch
onChange={(e, { value }) => {
setLoading(true);
updateQueryParam('wcaId', value.id);
}}
multiple={false}
model="person"
/>
)}
</>
);
}
export default EditPerson;
28 changes: 28 additions & 0 deletions app/webpacker/lib/hooks/useQueryParams.js
@@ -0,0 +1,28 @@
import { useCallback, useEffect, useState } from 'react';

function getQueryParamsFromBrowserUrl() {
return Object.fromEntries(new URLSearchParams(window.location.search));
}

export default function useQueryParams() {
const [queryParams, setQueryParams] = useState(getQueryParamsFromBrowserUrl());

useEffect(() => {
const searchParams = new URLSearchParams(queryParams).toString();
const currentSearchParams = window.location.search.startsWith('?')
? window.location.search.split('?')[1]
: window.location.search;
if (currentSearchParams !== searchParams) {
window.location.search = searchParams;
}
}, [queryParams]);

const updateQueryParam = useCallback((key, value) => {
setQueryParams({
...queryParams,
[key]: value,
});
}, [queryParams]);

return [queryParams, updateQueryParam];
}
8 changes: 7 additions & 1 deletion app/webpacker/lib/requests/routes.js.erb
Expand Up @@ -168,6 +168,9 @@ export const apiV0Urls = {
permissions: `<%= CGI.unescape(Rails.application.routes.url_helpers.api_v0_users_me_permissions_path) %>`,
},
},
persons: {
show: (wcaId) => `<%= CGI.unescape(Rails.application.routes.url_helpers.api_v0_persons_path) %>/${wcaId}`,
},
wrt: {
edit: (wcaId) => `<%= CGI.unescape(Rails.application.routes.url_helpers.api_v0_wrt_person_path("${wcaId}"))%>`,
destroy: (wcaId) => `<%= CGI.unescape(Rails.application.routes.url_helpers.api_v0_wrt_person_path("${wcaId}"))%>`,
Expand Down Expand Up @@ -198,5 +201,8 @@ export const panelUrls = {
},
wst: {
translators: `<%= CGI.unescape(Rails.application.routes.url_helpers.panel_wst_path(anchor: PanelController.panel_list['wst']['translators'])) %>`,
}
},
wrt: {
editPerson: (wcaId) => `<%= CGI.unescape(Rails.application.routes.url_helpers.panel_wrt_path(wcaId: '${wcaId}', anchor: PanelController.panel_list['wrt']['editPerson'])) %>`,
},
}

0 comments on commit b0a7c5c

Please sign in to comment.