Skip to content

Commit

Permalink
React Admin - events, competitions, series - eh? (#233)
Browse files Browse the repository at this point in the history
* react admin: event management (unfinished)

* unify pessimistic mutationMode with redirect to show

* MyCreate to unify redirect to show on create going forward

* some competition management, will be tested/adjusted later

* some series management

* new BE endpoint for competition slug, old used for ID access
  • Loading branch information
rtrembecky authored Dec 8, 2023
1 parent 828caf1 commit 7224c59
Show file tree
Hide file tree
Showing 20 changed files with 511 additions and 14 deletions.
23 changes: 20 additions & 3 deletions src/components/Admin/Admin.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
import {FC} from 'react'
import {Admin as ReactAdmin, Resource} from 'react-admin'

import {CompetitionList} from './Competition/CompetitionList'
import {dataProvider} from './dataProvider'
import {PostCreate} from './resources/cms/post/PostCreate'
import {PostEdit} from './resources/cms/post/PostEdit'
import {PostList} from './resources/cms/post/PostList'
import {PostShow} from './resources/cms/post/PostShow'
import {CompetitionCreate} from './resources/competition/competition/CompetitionCreate'
import {CompetitionEdit} from './resources/competition/competition/CompetitionEdit'
import {CompetitionList} from './resources/competition/competition/CompetitionList'
import {CompetitionShow} from './resources/competition/competition/CompetitionShow'
import {EventCreate} from './resources/competition/event/EventCreate'
import {EventEdit} from './resources/competition/event/EventEdit'
import {EventList} from './resources/competition/event/EventList'
import {EventShow} from './resources/competition/event/EventShow'
import {SeriesEdit} from './resources/competition/series/SeriesEdit'
import {SeriesList} from './resources/competition/series/SeriesList'
import {SeriesShow} from './resources/competition/series/SeriesShow'
import {useAuthProvider} from './useAuthProvider'

export const Admin: FC = () => {
Expand All @@ -15,8 +25,15 @@ export const Admin: FC = () => {
return (
<ReactAdmin authProvider={authProvider} dataProvider={dataProvider}>
<Resource name="cms/post" list={PostList} edit={PostEdit} show={PostShow} create={PostCreate} />
{/* TODO: create, edit, celkovo rozumne rozhranie pre sutaze/serie */}
<Resource name="competition/series" list={CompetitionList} />
<Resource name="competition/series" list={SeriesList} edit={SeriesEdit} show={SeriesShow} />
<Resource name="competition/event" list={EventList} edit={EventEdit} show={EventShow} create={EventCreate} />
<Resource
name="competition/competition"
list={CompetitionList}
edit={CompetitionEdit}
show={CompetitionShow}
create={CompetitionCreate}
/>
</ReactAdmin>
)
}
13 changes: 13 additions & 0 deletions src/components/Admin/custom/CompetitionField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {ComponentProps, FC} from 'react'
import {SelectField, useGetList} from 'react-admin'

export const CompetitionField: FC<ComponentProps<typeof SelectField>> = (props) => {
const {data, isLoading, error} = useGetList('competition/competition')

const typedData = data as {id: number; name: string}[]

if (isLoading) return <span>Loading...</span>
if (error) return <span>Error occured loading competitions: {error.message}</span>

return <SelectField choices={typedData} {...props} />
}
13 changes: 13 additions & 0 deletions src/components/Admin/custom/CompetitionInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {ComponentProps, FC} from 'react'
import {SelectInput, useGetList} from 'react-admin'

export const CompetitionInput: FC<ComponentProps<typeof SelectInput>> = (props) => {
const {data, isLoading, error} = useGetList('competition/competition')

const typedData = data as {id: number; name: string}[]

if (isLoading) return <span>Loading...</span>
if (error) return <span>Error occured loading competitions: {error.message}</span>

return <SelectInput choices={typedData} {...props} />
}
12 changes: 12 additions & 0 deletions src/components/Admin/custom/JsonField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {FC} from 'react'
import {FieldProps, useRecordContext} from 'react-admin'

export const JsonField: FC<FieldProps> = ({source}) => {
const record = useRecordContext()
if (!record || !source) return null

const value = record[source]
const text = JSON.stringify(value, null, 2)

return <pre>{text}</pre>
}
4 changes: 4 additions & 0 deletions src/components/Admin/custom/MyCreate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {FC, PropsWithChildren} from 'react'
import {Create} from 'react-admin'

export const MyCreate: FC<PropsWithChildren> = ({children}) => <Create redirect="show">{children}</Create>
10 changes: 10 additions & 0 deletions src/components/Admin/custom/MyEdit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {FC, PropsWithChildren} from 'react'
import {Edit} from 'react-admin'

import {MyEditActions} from './MyEditActions'

export const MyEdit: FC<PropsWithChildren> = ({children}) => (
<Edit actions={<MyEditActions />} mutationMode="pessimistic" redirect="show">
{children}
</Edit>
)
6 changes: 3 additions & 3 deletions src/components/Admin/resources/cms/post/PostCreate.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {FC} from 'react'
import {
ArrayInput,
Create,
DateTimeInput,
FormTab,
NumberInput,
Expand All @@ -11,10 +10,11 @@ import {
TextInput,
} from 'react-admin'

import {MyCreate} from '@/components/Admin/custom/MyCreate'
import {SitesCheckboxInput} from '@/components/Admin/custom/SitesCheckboxInput'

export const PostCreate: FC = () => (
<Create redirect="show">
<MyCreate>
<TabbedForm>
<FormTab label="general">
<NumberInput source="id" fullWidth disabled />
Expand All @@ -36,5 +36,5 @@ export const PostCreate: FC = () => (
</ArrayInput>
</FormTab>
</TabbedForm>
</Create>
</MyCreate>
)
7 changes: 3 additions & 4 deletions src/components/Admin/resources/cms/post/PostEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {FC} from 'react'
import {
ArrayInput,
DateTimeInput,
Edit,
FormTab,
NumberInput,
required,
Expand All @@ -11,11 +10,11 @@ import {
TextInput,
} from 'react-admin'

import {MyEditActions} from '@/components/Admin/custom/MyEditActions'
import {MyEdit} from '@/components/Admin/custom/MyEdit'
import {SitesCheckboxInput} from '@/components/Admin/custom/SitesCheckboxInput'

export const PostEdit: FC = () => (
<Edit actions={<MyEditActions />} redirect="show" mutationMode="undoable">
<MyEdit>
<TabbedForm>
<FormTab label="general">
<NumberInput source="id" fullWidth disabled />
Expand All @@ -37,5 +36,5 @@ export const PostEdit: FC = () => (
</ArrayInput>
</FormTab>
</TabbedForm>
</Edit>
</MyEdit>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {FC} from 'react'
import {
ArrayInput,
DateTimeInput,
FormTab,
NumberInput,
required,
SimpleFormIterator,
TabbedForm,
TextInput,
} from 'react-admin'

import {MyCreate} from '@/components/Admin/custom/MyCreate'
import {SitesCheckboxInput} from '@/components/Admin/custom/SitesCheckboxInput'

export const CompetitionCreate: FC = () => (
<MyCreate>
<TabbedForm>
<FormTab label="general">
{/* <NumberInput source="id" fullWidth disabled /> */}
<TextInput source="name" fullWidth validate={required()} />
<NumberInput source="start_year" fullWidth validate={required()} />
<TextInput source="description" fullWidth />
<TextInput source="rules" fullWidth />
{/* TODO: radio buttons / select */}
<NumberInput source="competition_type" fullWidth validate={required()} />
<NumberInput source="min_years_until_graduation" fullWidth />
<SitesCheckboxInput source="sites" validate={required()} />
</FormTab>
{/* maju sa dat eventy vytvarat pri tvoreni competition? */}
<FormTab label="events">
<ArrayInput source="event_set" defaultValue={[]}>
<SimpleFormIterator>
{/* <NumberInput source="id" fullWidth disabled /> */}
<NumberInput source="year" fullWidth />
<TextInput source="school_year" fullWidth /* validate={required()} */ />
<DateTimeInput source="start" fullWidth validate={required()} />
<DateTimeInput source="end" fullWidth validate={required()} />
<NumberInput source="competition" fullWidth />
{/* unspecifiedpublication_set: UnspecifiedPublication[]
registration_links: RegistrationLink[] */}
</SimpleFormIterator>
</ArrayInput>
</FormTab>
</TabbedForm>
</MyCreate>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {FC} from 'react'
import {ArrayInput, FormTab, NumberInput, required, SimpleFormIterator, TabbedForm, TextInput} from 'react-admin'

import {MyEdit} from '@/components/Admin/custom/MyEdit'
import {SitesCheckboxInput} from '@/components/Admin/custom/SitesCheckboxInput'

export const CompetitionEdit: FC = () => (
<MyEdit>
<TabbedForm>
<FormTab label="general">
<NumberInput source="id" fullWidth disabled />
<TextInput source="name" fullWidth />
<NumberInput source="start_year" fullWidth />
<TextInput source="description" fullWidth />
<TextInput source="rules" fullWidth />
<NumberInput source="competition_type" fullWidth />
<NumberInput source="min_years_until_graduation" fullWidth />
<SitesCheckboxInput source="sites" validate={required()} />
</FormTab>
<FormTab label="events">
<ArrayInput source="event_set" defaultValue={[]}>
<SimpleFormIterator>
<NumberInput source="id" fullWidth disabled />
{/* unspecifiedpublication_set: UnspecifiedPublication[]
registration_links: RegistrationLink[] */}
<NumberInput source="year" fullWidth />
<TextInput source="shool_year" fullWidth /* validate={required()} */ />
<TextInput source="start" fullWidth validate={required()} />
<TextInput source="end" fullWidth validate={required()} />
<NumberInput source="competition" fullWidth />
</SimpleFormIterator>
</ArrayInput>
</FormTab>
</TabbedForm>
</MyEdit>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {FC} from 'react'
import {Datagrid, FunctionField, List, NumberField, RaRecord, TextField} from 'react-admin'

import {SitesArrayField} from '@/components/Admin/custom/SitesArrayField'
import {TruncatedTextField} from '@/components/Admin/custom/TruncatedTextField'

export const CompetitionList: FC = () => (
<List>
<Datagrid rowClick="show">
<NumberField source="id" />
<TextField source="name" />
<TextField source="slug" />
<NumberField source="start_year" />
<TruncatedTextField source="description" maxTextWidth={30} />
<TruncatedTextField source="rules" maxTextWidth={30} />
{/* <NumberField source="competition_type.id" /> */}
<TextField source="competition_type.name" label="Competition type" />
<SitesArrayField source="sites" />
<TextField source="who_can_participate" />
<NumberField source="min_years_until_graduation" />
<FunctionField<RaRecord>
source="history_events"
label="History events count"
render={(record) => record && <span>{record['history_events'].length}</span>}
/>
</Datagrid>
</List>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {FC} from 'react'
import {
ArrayField,
Datagrid,
DateField,
NumberField,
Show,
SimpleShowLayout,
Tab,
TabbedShowLayout,
TextField,
} from 'react-admin'

import {JsonField} from '@/components/Admin/custom/JsonField'
import {MyShowActions} from '@/components/Admin/custom/MyShowActions'
import {SitesArrayField} from '@/components/Admin/custom/SitesArrayField'
import {TruncatedTextField} from '@/components/Admin/custom/TruncatedTextField'

export const CompetitionShow: FC = () => (
<Show actions={<MyShowActions />}>
<TabbedShowLayout>
<Tab label="general">
<SimpleShowLayout>
<NumberField source="id" />
<TextField source="name" />
<TextField source="slug" />
<NumberField source="start_year" />
<TextField source="description" />
<TruncatedTextField source="rules" maxTextWidth={200} />
<NumberField source="competition_type.id" />
<TextField source="competition_type.name" />
<SitesArrayField source="sites" />
<NumberField source="min_years_until_graduation" />
<TextField source="who_can_participate" />
<JsonField source="upcoming_or_current_event" />
</SimpleShowLayout>
</Tab>
<Tab label="history_events">
<SimpleShowLayout>
<ArrayField source="history_events">
<Datagrid>
<NumberField source="id" />
<NumberField source="year" />
<TextField source="school_year" />
<DateField source="start" />
<DateField source="end" />
<NumberField source="season_code" />
<NumberField source="competition" />
</Datagrid>
</ArrayField>
</SimpleShowLayout>
</Tab>
</TabbedShowLayout>
</Show>
)
51 changes: 51 additions & 0 deletions src/components/Admin/resources/competition/event/EventCreate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {FC} from 'react'
import {
ArrayInput,
DateTimeInput,
FormTab,
NumberInput,
required,
SimpleFormIterator,
TabbedForm,
TextInput,
} from 'react-admin'

import {CompetitionInput} from '@/components/Admin/custom/CompetitionInput'
import {MyCreate} from '@/components/Admin/custom/MyCreate'

export const EventCreate: FC = () => (
<MyCreate>
<TabbedForm>
<FormTab label="general">
<NumberInput source="id" fullWidth disabled />
<NumberInput source="year" fullWidth validate={required()} />
<TextInput source="school_year" fullWidth validate={required()} />
<span>napr. 2023/2024</span>
<DateTimeInput source="start" fullWidth validate={required()} />
<DateTimeInput source="end" fullWidth validate={required()} />
<CompetitionInput source="competition" fullWidth validate={required()} />

<span>TODO: always sends null as registration_link</span>
<TextInput source="registration_link" fullWidth hidden disabled defaultValue={null} parse={() => null} />
{/* <NumberInput source="registration_link.id" fullWidth disabled />
<TextInput source="registration_link.url" fullWidth />
<DateInput source="registration_link.start" fullWidth />
<DateInput source="registration_link.end" fullWidth />
<TextInput source="registration_link.additional_info" fullWidth /> */}
</FormTab>
<FormTab label="publications">
<span>TODO: publikacie treba vediet nahrat, nie tu editovat db</span>
<ArrayInput source="publication_set" defaultValue={[]}>
<SimpleFormIterator>
<NumberInput source="id" fullWidth disabled />
<TextInput source="name" fullWidth validate={required()} />
<TextInput source="file" fullWidth validate={required()} />
<NumberInput source="publication_type" fullWidth />
<NumberInput source="event" fullWidth disabled />
<NumberInput source="order" fullWidth />
</SimpleFormIterator>
</ArrayInput>
</FormTab>
</TabbedForm>
</MyCreate>
)
Loading

0 comments on commit 7224c59

Please sign in to comment.