Major update

This commit is contained in:
2023-06-01 08:52:05 -05:00
parent d7c0f373f4
commit df84287eb2
264 changed files with 8614 additions and 964 deletions

View File

@@ -1,3 +1,3 @@
.content {
padding: 30px;
}
padding: 30px;
}

View File

@@ -1,14 +1,19 @@
import React from 'react';
import styles from './App.module.scss'
import styles from './App.module.scss';
import { Routes, Route } from 'react-router-dom';
import { initializeIcons } from '@fluentui/font-icons-mdl2';
import { Grid, Sidebar } from 'semantic-ui-react';
import Header from '../header/Header';
import Footer from '../footer/Footer';
import Navigation from '../navigation/Navigation';
import Divisions from '../divisions/Divisions';
import Leagues from '../leagues/Leagues';
import Seasons from '../seasons/Seasons';
import Sports from '../sports/Sports';
import Teams from '../teams/Teams';
import Venues from '../venues/Venues';
import { useSidebarContext } from '../../hooks/sidebarContext/UseSidebarContext';
import { usePagination } from '../..//hooks/usePaginiation/UsePagination';
initializeIcons();
@@ -18,7 +23,7 @@ const App: React.FC<unknown> = () => {
return (
<Sidebar.Pushable>
<Sidebar.Pusher dimmed={sidebarContext.state.sidebar?.visible}>
<Header />
<Header />
<Grid columns={16}>
<Grid.Row>
<Grid.Column width={3}>
@@ -26,6 +31,18 @@ const App: React.FC<unknown> = () => {
</Grid.Column>
<Grid.Column width={12}>
<div className={styles.content}>
<Routes>
<Route path='divisions' element={<Divisions />} />
</Routes>
<Routes>
<Route path='leagues' element={<Leagues />} />
</Routes>
<Routes>
<Route path='seasons' element={<Seasons />} />
</Routes>
<Routes>
<Route path='sports' element={<Sports />} />
</Routes>
<Routes>
<Route path='teams' element={<Teams />} />
</Routes>
@@ -36,7 +53,7 @@ const App: React.FC<unknown> = () => {
</Grid.Column>
</Grid.Row>
</Grid>
<Footer />
{/* <Footer /> */}
</Sidebar.Pusher>
</Sidebar.Pushable>
);

View File

@@ -0,0 +1,171 @@
import React, { SyntheticEvent, useEffect, useReducer } from 'react';
import { useQuery } from '@apollo/client';
import { MessageBar, MessageBarType } from '@fluentui/react/lib/MessageBar';
import { initialState, reducer } from './reducer';
import { useAppContext } from '../../hooks/appContext/UseAppContext';
import { useSidebarContext } from '../../hooks/sidebarContext/UseSidebarContext';
import { GET_DIVISIONS } from '../../constants/graphQL';
import { INotification } from '../../models/INotification';
import {
Button,
Grid,
Header,
Icon,
Loader,
Pagination,
Sidebar,
Table
} from 'semantic-ui-react';
import { usePagination } from '../../hooks/usePaginiation/UsePagination';
const Venues: React.FC<unknown> = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const appContext = useAppContext();
const sidebarContext = useSidebarContext();
const currentPageNumber = state.currentPageNumber;
const pageSize = state.pageSize;
const { data, loading, error, refetch } = useQuery(GET_DIVISIONS, {
variables: {
pageNumber: currentPageNumber,
pageSize: pageSize
}
});
const { pagination } = usePagination();
const columns: string[] = ['Name', ''];
const onDismissMessageBar = () => {
const notification: INotification = {
...appContext.state.notification,
isVisible: false
};
appContext.dispatch({ type: 'SET_NOTIFICATION', payload: notification });
};
const onPageChange = (event: SyntheticEvent, data: any) => {
const newCurrentPage: number = data.activePage;
dispatch({ type: 'SET_CURRENT_PAGE_NUMBER', payload: newCurrentPage });
};
const onDetails = (id: number) => {
// sidebarContext.dispatch({
// type: 'SET_SIDEBAR',
// payload: {
// sidebar: {
// visible: true,
// animation: 'overlay',
// width: 'very wide',
// direction: 'right'
// },
// content: <VenueDetails venueId={id} />
// }
// });
};
useEffect(() => {
if (data) {
dispatch({
type: 'SET_ITEMS',
payload: data.divisions
});
}
}, [data]);
useEffect(() => {
// console.log(error);
const notification: INotification = {
messageBarType: MessageBarType.error,
message: error?.message,
isMultiline: false,
isVisible: false
};
appContext.dispatch({ type: 'SET_NOTIFICATION', payload: notification });
}, [error]);
useEffect(() => {
refetch({
pageNumber: currentPageNumber,
pageSize: pageSize
});
}, [currentPageNumber]);
return (
<Grid columns={1}>
<Grid.Row>
<Header as='h1'>Divisions</Header>
</Grid.Row>
{appContext.state.notification?.isVisible && (
<Grid.Row>
<Grid.Column>
<MessageBar
messageBarType={appContext.state.notification?.messageBarType}
isMultiline={appContext.state.notification?.isMultiline}
onDismiss={onDismissMessageBar}
>
{appContext.state.notification?.message}
</MessageBar>
</Grid.Column>
</Grid.Row>
)}
<Grid.Row>
<Grid.Column>
{loading && (
<Loader size='massive' active={loading}>
Loading...
</Loader>
)}
{!loading && (
<Table selectable>
<Table.Header>
<Table.Row>
{columns.map((column: string, index: number) => {
return (
<Table.HeaderCell key={index}>{column}</Table.HeaderCell>
);
})}
</Table.Row>
</Table.Header>
<Table.Body>
{state.items?.map((item) => {
return (
<Table.Row key={item.id}>
<Table.Cell>{item.name}</Table.Cell>
<Table.Cell textAlign='right'>
<Button basic icon onClick={() => onDetails(item.id)}>
<Icon name='info circle' />
</Button>
</Table.Cell>
</Table.Row>
);
})}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan='2'>
<Grid columns={1}>
<Grid.Row>
<Grid.Column textAlign='right'>
<Pagination
totalPages={pagination ? pagination.TotalPages : ''}
activePage={state.currentPageNumber}
onPageChange={onPageChange}
size='mini'
/>
</Grid.Column>
</Grid.Row>
</Grid>
</Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
)}
</Grid.Column>
</Grid.Row>
</Grid>
);
};
export default Venues;

View File

@@ -0,0 +1,8 @@
import { IDivision } from '../../models/IDivision';
export interface IDivisionsState {
items: IDivision[];
currentPageNumber: number;
pageSize: number;
isPanelOpen: boolean;
}

View File

@@ -0,0 +1,50 @@
import { IDivisionsState } from './IDivisionsState';
import { IDivision } from '../../models/IDivision';
export type Action =
| { type: 'SET_ITEMS'; payload: IDivision[] }
| { type: 'SET_CURRENT_PAGE_NUMBER'; payload: number }
| { type: 'SET_PAGE_SIZE'; payload: number }
| { type: 'SET_IS_PANEL_OPEN'; payload: boolean };
export const initialState: IDivisionsState = {
items: [],
currentPageNumber: 1,
pageSize: 10,
isPanelOpen: false
};
export const reducer = (
state: IDivisionsState,
action: Action
): IDivisionsState => {
switch (action.type) {
case 'SET_ITEMS': {
return {
...state,
items: action.payload
};
}
case 'SET_CURRENT_PAGE_NUMBER': {
return {
...state,
currentPageNumber: action.payload
};
}
case 'SET_PAGE_SIZE': {
return {
...state,
pageSize: action.payload
};
}
case 'SET_IS_PANEL_OPEN': {
return {
...state,
isPanelOpen: action.payload
};
}
default: {
return state;
}
}
};

View File

@@ -1,4 +1,4 @@
.siteFooter {
background-color: #e0e1e2;
height: 150px;
}
background-color: #e0e1e2;
height: 150px;
}

View File

@@ -3,20 +3,18 @@ import styles from './Footer.module.scss';
import { Grid } from 'semantic-ui-react';
const Footer: React.FC<unknown> = () => {
return (
<div className={styles.siteFooter}>
<Grid columns={16}>
<Grid.Row>
<Grid.Column width={8}>
Hello!
</Grid.Column>
<Grid.Column width={8} textAlign='right'>
Goodbye!
</Grid.Column>
</Grid.Row>
</Grid>
</div>
)
}
return (
<div className={styles.siteFooter}>
<Grid columns={16}>
<Grid.Row>
<Grid.Column width={8}>Hello!</Grid.Column>
<Grid.Column width={8} textAlign='right'>
Goodbye!
</Grid.Column>
</Grid.Row>
</Grid>
</div>
);
};
export default Footer;
export default Footer;

View File

@@ -1,4 +1,4 @@
.siteHeader {
background-color: #e0e1e2;
height: 100px;
}
background-color: #e0e1e2;
height: 100px;
}

View File

@@ -3,20 +3,20 @@ import styles from './Header.module.scss';
import { Grid, Icon } from 'semantic-ui-react';
const Header: React.FC<unknown> = () => {
return (
<div className={styles.siteHeader}>
<Grid columns={16}>
<Grid.Row>
<Grid.Column width={8}>
<Icon name='baseball ball' size='huge' />
</Grid.Column>
<Grid.Column width={8} textAlign='right'>
Goodbye!
</Grid.Column>
</Grid.Row>
</Grid>
</div>
)
}
return (
<div className={styles.siteHeader}>
<Grid columns={16}>
<Grid.Row>
<Grid.Column width={8}>
<Icon name='baseball ball' size='huge' />
</Grid.Column>
<Grid.Column width={8} textAlign='right'>
Goodbye!
</Grid.Column>
</Grid.Row>
</Grid>
</div>
);
};
export default Header;
export default Header;

View File

@@ -0,0 +1,8 @@
import { ILeague } from '../../models/ILeague';
export interface ILeaguesState {
items: ILeague[];
currentPageNumber: number;
pageSize: number;
isPanelOpen: boolean;
}

View File

@@ -0,0 +1,173 @@
import React, { SyntheticEvent, useEffect, useReducer } from 'react';
import { useQuery } from '@apollo/client';
import { MessageBar, MessageBarType } from '@fluentui/react/lib/MessageBar';
import { initialState, reducer } from './reducer';
import { useAppContext } from '../../hooks/appContext/UseAppContext';
import { useSidebarContext } from '../../hooks/sidebarContext/UseSidebarContext';
import { GET_LEAGUES } from '../../constants/graphQL';
import { INotification } from '../../models/INotification';
import {
Button,
Grid,
Header,
Icon,
Loader,
Pagination,
Sidebar,
Table
} from 'semantic-ui-react';
// import VenueDetails from '../venueDetails/VenueDetails';
import { usePagination } from '../../hooks/usePaginiation/UsePagination';
const Leagues: React.FC<unknown> = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const appContext = useAppContext();
const sidebarContext = useSidebarContext();
const currentPageNumber = state.currentPageNumber;
const pageSize = state.pageSize;
const { data, loading, error, refetch } = useQuery(GET_LEAGUES, {
variables: {
pageNumber: currentPageNumber,
pageSize: pageSize
}
});
const { pagination } = usePagination();
const columns: string[] = ['Name', ''];
const onDismissMessageBar = () => {
const notification: INotification = {
...appContext.state.notification,
isVisible: false
};
appContext.dispatch({ type: 'SET_NOTIFICATION', payload: notification });
};
const onPageChange = (event: SyntheticEvent, data: any) => {
const newCurrentPage: number = data.activePage;
dispatch({ type: 'SET_CURRENT_PAGE_NUMBER', payload: newCurrentPage });
};
const onDetails = (id: number) => {
// sidebarContext.dispatch({
// type: 'SET_SIDEBAR',
// payload: {
// sidebar: {
// visible: true,
// animation: 'overlay',
// width: 'very wide',
// direction: 'right'
// },
// content: <VenueDetails venueId={id} />
// }
// });
};
useEffect(() => {
console.log(data)
if (data) {
dispatch({
type: 'SET_ITEMS',
payload: data.leagues
});
}
}, [data]);
useEffect(() => {
// console.log(error);
const notification: INotification = {
messageBarType: MessageBarType.error,
message: error?.message,
isMultiline: false,
isVisible: false
};
appContext.dispatch({ type: 'SET_NOTIFICATION', payload: notification });
}, [error]);
useEffect(() => {
refetch({
pageNumber: currentPageNumber,
pageSize: pageSize
});
}, [currentPageNumber]);
return (
<Grid columns={1}>
<Grid.Row>
<Header as='h1'>Leagues</Header>
</Grid.Row>
{appContext.state.notification?.isVisible && (
<Grid.Row>
<Grid.Column>
<MessageBar
messageBarType={appContext.state.notification?.messageBarType}
isMultiline={appContext.state.notification?.isMultiline}
onDismiss={onDismissMessageBar}
>
{appContext.state.notification?.message}
</MessageBar>
</Grid.Column>
</Grid.Row>
)}
<Grid.Row>
<Grid.Column>
{loading && (
<Loader size='massive' active={loading}>
Loading...
</Loader>
)}
{!loading && (
<Table selectable>
<Table.Header>
<Table.Row>
{columns.map((column: string, index: number) => {
return (
<Table.HeaderCell key={index}>{column}</Table.HeaderCell>
);
})}
</Table.Row>
</Table.Header>
<Table.Body>
{state.items.map((item) => {
return (
<Table.Row key={item.id}>
<Table.Cell>{item.name}</Table.Cell>
<Table.Cell textAlign='right'>
<Button basic icon onClick={() => onDetails(item.id)}>
<Icon name='info circle' />
</Button>
</Table.Cell>
</Table.Row>
);
})}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan='2'>
<Grid columns={1}>
<Grid.Row>
<Grid.Column textAlign='right'>
<Pagination
totalPages={pagination ? pagination.TotalPages : ''}
activePage={state.currentPageNumber}
onPageChange={onPageChange}
size='mini'
/>
</Grid.Column>
</Grid.Row>
</Grid>
</Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
)}
</Grid.Column>
</Grid.Row>
</Grid>
);
};
export default Leagues;

View File

@@ -0,0 +1,50 @@
import { ILeaguesState } from './ILeaguesState';
import { ILeague } from '../../models/ILeague';
export type Action =
| { type: 'SET_ITEMS'; payload: ILeague[] }
| { type: 'SET_CURRENT_PAGE_NUMBER'; payload: number }
| { type: 'SET_PAGE_SIZE'; payload: number }
| { type: 'SET_IS_PANEL_OPEN'; payload: boolean };
export const initialState: ILeaguesState = {
items: [],
currentPageNumber: 1,
pageSize: 10,
isPanelOpen: false
};
export const reducer = (
state: ILeaguesState,
action: Action
): ILeaguesState => {
switch (action.type) {
case 'SET_ITEMS': {
return {
...state,
items: action.payload
};
}
case 'SET_CURRENT_PAGE_NUMBER': {
return {
...state,
currentPageNumber: action.payload
};
}
case 'SET_PAGE_SIZE': {
return {
...state,
pageSize: action.payload
};
}
case 'SET_IS_PANEL_OPEN': {
return {
...state,
isPanelOpen: action.payload
};
}
default: {
return state;
}
}
};

View File

@@ -35,29 +35,22 @@ const Navigation: React.FC<unknown> = (props) => {
const [state, dispatch] = useReducer(reducer, initialState);
const location = useLocation();
const navigate = useNavigate();
const menuItems: string[] = [
'gameday',
'teams',
'venues'
];
const menuItems: string[] = ['gameday', 'divisions', 'leagues', 'seasons', 'sports', 'teams', 'venues'];
const onMenuItemClicked = (event: any, { name }: any) => {
navigate(name);
dispatch({ type: 'SET_ACTIVE_MENU_ITEM', payload: name });
}
};
useEffect(() => {
const activeLink: string = location.pathname === '/' ? 'home' : location.pathname.replace('/', '')
const activeLink: string =
location.pathname === '/' ? 'home' : location.pathname.replace('/', '');
dispatch({ type: 'SET_ACTIVE_MENU_ITEM', payload: activeLink });
}, [])
}, []);
return (
<Menu
pointing
secondary
vertical
>
<Menu pointing secondary vertical>
{menuItems.map((menuItem: string) => {
return (
<Menu.Item
@@ -66,10 +59,10 @@ const Navigation: React.FC<unknown> = (props) => {
active={state.activeLink === menuItem}
onClick={onMenuItemClicked}
/>
)
);
})}
</Menu>
)
}
);
};
export default Navigation;

View File

@@ -1,19 +1,21 @@
import { INavigationState } from "./INavigationState"
import { INavigationState } from './INavigationState';
export type Action =
| { type: 'SET_ACTIVE_MENU_ITEM', payload: string }
export type Action = { type: 'SET_ACTIVE_MENU_ITEM'; payload: string };
export const initialState: INavigationState = {
activeLink: ''
}
activeLink: ''
};
export const reducer = (state: INavigationState, action: Action): INavigationState => {
switch (action.type) {
case 'SET_ACTIVE_MENU_ITEM': {
return {
...state,
activeLink: action.payload
}
}
export const reducer = (
state: INavigationState,
action: Action
): INavigationState => {
switch (action.type) {
case 'SET_ACTIVE_MENU_ITEM': {
return {
...state,
activeLink: action.payload
};
}
}
}
};

View File

@@ -0,0 +1,4 @@
export interface INewSeasonModalProps {
isModalOpen: boolean;
onCloseModal: () => void;
}

View File

@@ -0,0 +1,8 @@
import { HubConnection } from "@microsoft/signalr";
export interface INewSeasonModalState {
connection: HubConnection | undefined,
year: string;
percentComplete: number;
loading: boolean;
}

View File

@@ -0,0 +1,134 @@
import React, { SyntheticEvent, useEffect, useReducer } from 'react';
import { initialState, reducer } from './reducer';
import {
Button,
Grid,
Icon,
Input,
Modal,
Progress
} from 'semantic-ui-react';
import { INewSeasonModalProps } from './INewSeasonModalProps';
import { HubConnection, HubConnectionBuilder } from '@microsoft/signalr';
import { ISeasonMessage } from '../../models/ISeasonMessage';
const NewSeasonModal: React.FC<INewSeasonModalProps> = ({ isModalOpen, onCloseModal }: INewSeasonModalProps) => {
const [state, dispatch] = useReducer(reducer, initialState);
const topic = 'ReceiveSeasonMessage';
const onYearChanged = (event: SyntheticEvent, data: any) => {
dispatch({ type: 'SET_YEAR', payload: data['value']})
}
const onOk = () => {
dispatch({ type: 'SET_IS_LOADING', payload: true });
}
useEffect(() => {
if (isModalOpen) {
const newConnection: HubConnection = new HubConnectionBuilder()
.withUrl('http://localhost:5580/hubs/season')
.withAutomaticReconnect()
.build();
dispatch({ type: 'SET_CONNECTION', payload: newConnection });
} else {
if (state.connection) {
state.connection.stop();
dispatch({ type: 'SET_CONNECTION', payload: undefined });
}
}
}, [isModalOpen])
useEffect(() => {
if (state.connection) {
const connection: HubConnection = state.connection;
connection.start().then((result) => {
console.log('connected');
connection.on(topic, (message: ISeasonMessage) => {
console.log(message);
dispatch({ type: 'SET_PERCENT_COMPLETE', payload: Math.floor((message.datesCompleted / message.totalDates) * 100) })
})
}).catch((error) => {
console.log(`Connection failed with the following message: ${error}`);
})
}
}, [state.connection]);
useEffect(() => {
if (state.percentComplete === 100) {
onCloseModal();
dispatch({ type: 'SET_PERCENT_COMPLETE', payload: 0 })
}
}, [state.percentComplete])
return (
<Modal
open={isModalOpen}
onClose={onCloseModal}
closeOnEscape={false}
closeOnDimmerClick={false}
>
<Modal.Header>
Add New Season
</Modal.Header>
<Modal.Content>
<Grid columns={1}>
{!state.loading &&
<React.Fragment>
<Grid.Row>
<span>Enter a year below and click <strong>OK</strong> to load games.</span>
</Grid.Row>
<Grid.Row>
<Input
label='Year'
onChange={onYearChanged}
/>
</Grid.Row>
</React.Fragment>
}
{state.loading &&
<Grid.Row>
<Grid.Column>
<Progress
percent={state.percentComplete}
indicating
progress
>
Loading games...
</Progress>
</Grid.Column>
</Grid.Row>
}
</Grid>
</Modal.Content>
<Modal.Actions>
<Button
icon
labelPosition='left'
onClick={onCloseModal}
disabled={state.loading}
>
<Icon name='cancel' />
Cancel
</Button>
<Button
primary
icon
labelPosition='left'
disabled={state.loading}
onClick={onOk}
>
<Icon name='check' />
OK
</Button>
</Modal.Actions>
</Modal>
)
}
export default NewSeasonModal;

View File

@@ -0,0 +1,47 @@
import { HubConnection } from "@microsoft/signalr";
import { INewSeasonModalState } from "./INewSeasonModalState";
type Action =
| { type: 'SET_CONNECTION'; payload: HubConnection | undefined }
| { type: 'SET_YEAR'; payload: string }
| { type: 'SET_PERCENT_COMPLETE'; payload: number }
| { type: 'SET_IS_LOADING'; payload: boolean };
export const initialState: INewSeasonModalState = {
connection: undefined,
year: '',
percentComplete: 0,
loading: false
}
export const reducer = (state: INewSeasonModalState, action: Action): INewSeasonModalState => {
switch (action.type) {
case 'SET_CONNECTION': {
return {
...state,
connection: action.payload
}
}
case 'SET_YEAR': {
return {
...state,
year: action.payload
}
}
case 'SET_PERCENT_COMPLETE': {
return {
...state,
percentComplete: action.payload
}
}
case 'SET_IS_LOADING': {
return {
...state,
loading: action.payload
}
}
default: {
return state;
}
}
}

View File

@@ -1,9 +1,7 @@
import React from 'react';
import { IPaginatorProps } from './IPaginatorProps';
import styles from './Paginator.module.scss';
import {
IconButton
} from '@fluentui/react/lib/Button';
import { IconButton } from '@fluentui/react/lib/Button';
import { Link } from '@fluentui/react/lib/Link';
const range = (start: number, end: number) => {

View File

@@ -0,0 +1,9 @@
import { ISeason } from '../../models/ISeason';
export interface ISeasonsState {
items: ISeason[];
currentPageNumber: number;
pageSize: number;
isPanelOpen: boolean;
isModalOpen: boolean;
}

View File

@@ -0,0 +1,202 @@
import React, { SyntheticEvent, useEffect, useReducer } from 'react';
import { useQuery } from '@apollo/client';
import { MessageBar, MessageBarType } from '@fluentui/react/lib/MessageBar';
import { initialState, reducer } from './reducer';
import { useAppContext } from '../../hooks/appContext/UseAppContext';
import { useSidebarContext } from '../../hooks/sidebarContext/UseSidebarContext';
import { GET_SEASONS } from '../../constants/graphQL';
import { INotification } from '../../models/INotification';
import {
Button,
Grid,
Header,
Icon,
Loader,
Pagination,
Sidebar,
Table
} from 'semantic-ui-react';
// import VenueDetails from '../venueDetails/VenueDetails';
import { usePagination } from '../../hooks/usePaginiation/UsePagination';
import NewSeasonModal from '../newSeasonDialog/NewSeasonModal';
const Seasons: React.FC<unknown> = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const appContext = useAppContext();
const sidebarContext = useSidebarContext();
const currentPageNumber = state.currentPageNumber;
const pageSize = state.pageSize;
const { data, loading, error, refetch } = useQuery(GET_SEASONS, {
variables: {
pageNumber: currentPageNumber,
pageSize: pageSize
}
});
const { pagination } = usePagination();
const columns: string[] = ['Name', ''];
const onDismissMessageBar = () => {
const notification: INotification = {
...appContext.state.notification,
isVisible: false
};
appContext.dispatch({ type: 'SET_NOTIFICATION', payload: notification });
};
const onPageChange = (event: SyntheticEvent, data: any) => {
const newCurrentPage: number = data.activePage;
dispatch({ type: 'SET_CURRENT_PAGE_NUMBER', payload: newCurrentPage });
};
const onDetails = (id: number) => {
// sidebarContext.dispatch({
// type: 'SET_SIDEBAR',
// payload: {
// sidebar: {
// visible: true,
// animation: 'overlay',
// width: 'very wide',
// direction: 'right'
// },
// content: <VenueDetails venueId={id} />
// }
// });
};
const onIsModalOpen = () => {
dispatch({ type: 'SET_IS_MODAL_OPEN', payload: !state.isModalOpen });
}
useEffect(() => {
if (data) {
dispatch({
type: 'SET_ITEMS',
payload: data.leagues
});
}
}, [data]);
useEffect(() => {
// console.log(error);
const notification: INotification = {
messageBarType: MessageBarType.error,
message: error?.message,
isMultiline: false,
isVisible: false
};
appContext.dispatch({ type: 'SET_NOTIFICATION', payload: notification });
}, [error]);
useEffect(() => {
refetch({
pageNumber: currentPageNumber,
pageSize: pageSize
});
}, [currentPageNumber]);
return (
<React.Fragment>
<Grid>
<Grid.Row columns={2}>
<Grid.Column >
<Header as='h1'>Seasons</Header>
</Grid.Column>
<Grid.Column textAlign='right'>
<Button
primary
icon
labelPosition='left'
onClick={onIsModalOpen}
>
<Icon name='add' />
Add
</Button>
</Grid.Column>
</Grid.Row>
{appContext.state.notification?.isVisible && (
<Grid.Row columns={1}>
<Grid.Column>
<MessageBar
messageBarType={appContext.state.notification?.messageBarType}
isMultiline={appContext.state.notification?.isMultiline}
onDismiss={onDismissMessageBar}
>
{appContext.state.notification?.message}
</MessageBar>
</Grid.Column>
</Grid.Row>
)}
<Grid.Row columns={1}>
<Grid.Column>
{loading && (
<Loader size='massive' active={loading}>
Loading...
</Loader>
)}
{!loading && state.items.length === 0 &&
<div>
<p>There are currently no seasons loaded.</p>
<p>Click <strong>Add</strong> to load a season.</p>
</div>
}
{!loading && state.items.length > 0 && (
<Table selectable>
<Table.Header>
<Table.Row>
{columns.map((column: string, index: number) => {
return (
<Table.HeaderCell key={index}>{column}</Table.HeaderCell>
);
})}
</Table.Row>
</Table.Header>
<Table.Body>
{state.items.map((item) => {
return (
<Table.Row key={item.id}>
<Table.Cell>{item.id}</Table.Cell>
<Table.Cell textAlign='right'>
<Button basic icon onClick={() => onDetails(item.id)}>
<Icon name='info circle' />
</Button>
</Table.Cell>
</Table.Row>
);
})}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan='2'>
<Grid columns={1}>
<Grid.Row>
<Grid.Column textAlign='right'>
<Pagination
totalPages={pagination ? pagination.TotalPages : ''}
activePage={state.currentPageNumber}
onPageChange={onPageChange}
size='mini'
/>
</Grid.Column>
</Grid.Row>
</Grid>
</Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
)}
</Grid.Column>
</Grid.Row>
</Grid>
<NewSeasonModal
isModalOpen={state.isModalOpen}
onCloseModal={onIsModalOpen}
/>
</React.Fragment>
);
};
export default Seasons;

View File

@@ -0,0 +1,58 @@
import { ISeasonsState } from './ISeasonsState';
import { ISeason } from '../../models/ISeason';
export type Action =
| { type: 'SET_ITEMS'; payload: ISeason[] }
| { type: 'SET_CURRENT_PAGE_NUMBER'; payload: number }
| { type: 'SET_PAGE_SIZE'; payload: number }
| { type: 'SET_IS_PANEL_OPEN'; payload: boolean }
| { type: 'SET_IS_MODAL_OPEN'; payload: boolean };
export const initialState: ISeasonsState = {
items: [],
currentPageNumber: 1,
pageSize: 10,
isPanelOpen: false,
isModalOpen: false,
};
export const reducer = (
state: ISeasonsState,
action: Action
): ISeasonsState => {
switch (action.type) {
case 'SET_ITEMS': {
return {
...state,
items: action.payload
};
}
case 'SET_CURRENT_PAGE_NUMBER': {
return {
...state,
currentPageNumber: action.payload
};
}
case 'SET_PAGE_SIZE': {
return {
...state,
pageSize: action.payload
};
}
case 'SET_IS_PANEL_OPEN': {
return {
...state,
isPanelOpen: action.payload
};
}
case 'SET_IS_MODAL_OPEN': {
return {
...state,
isModalOpen: action.payload
}
}
default: {
return state;
}
}
};

View File

@@ -0,0 +1,8 @@
import { ISport } from '../../models/ISport';
export interface ISportsState {
items: ISport[];
currentPageNumber: number;
pageSize: number;
isPanelOpen: boolean;
}

View File

@@ -0,0 +1,172 @@
import React, { SyntheticEvent, useEffect, useReducer } from 'react';
import { useQuery } from '@apollo/client';
import { MessageBar, MessageBarType } from '@fluentui/react/lib/MessageBar';
import { initialState, reducer } from './reducer';
import { useAppContext } from '../../hooks/appContext/UseAppContext';
import { useSidebarContext } from '../../hooks/sidebarContext/UseSidebarContext';
import { GET_SPORTS } from '../../constants/graphQL';
import { INotification } from '../../models/INotification';
import {
Button,
Grid,
Header,
Icon,
Loader,
Pagination,
Sidebar,
Table
} from 'semantic-ui-react';
// import VenueDetails from '../venueDetails/VenueDetails';
import { usePagination } from '../../hooks/usePaginiation/UsePagination';
const Sports: React.FC<unknown> = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const appContext = useAppContext();
const sidebarContext = useSidebarContext();
const currentPageNumber = state.currentPageNumber;
const pageSize = state.pageSize;
const { data, loading, error, refetch } = useQuery(GET_SPORTS, {
variables: {
pageNumber: currentPageNumber,
pageSize: pageSize
}
});
const { pagination } = usePagination();
const columns: string[] = ['Name', ''];
const onDismissMessageBar = () => {
const notification: INotification = {
...appContext.state.notification,
isVisible: false
};
appContext.dispatch({ type: 'SET_NOTIFICATION', payload: notification });
};
const onPageChange = (event: SyntheticEvent, data: any) => {
const newCurrentPage: number = data.activePage;
dispatch({ type: 'SET_CURRENT_PAGE_NUMBER', payload: newCurrentPage });
};
const onDetails = (id: number) => {
// sidebarContext.dispatch({
// type: 'SET_SIDEBAR',
// payload: {
// sidebar: {
// visible: true,
// animation: 'overlay',
// width: 'very wide',
// direction: 'right'
// },
// content: <VenueDetails venueId={id} />
// }
// });
};
useEffect(() => {
if (data) {
dispatch({
type: 'SET_ITEMS',
payload: data.sports
});
}
}, [data]);
useEffect(() => {
// console.log(error);
const notification: INotification = {
messageBarType: MessageBarType.error,
message: error?.message,
isMultiline: false,
isVisible: false
};
appContext.dispatch({ type: 'SET_NOTIFICATION', payload: notification });
}, [error]);
useEffect(() => {
refetch({
pageNumber: currentPageNumber,
pageSize: pageSize
});
}, [currentPageNumber]);
return (
<Grid columns={1}>
<Grid.Row>
<Header as='h1'>Sports</Header>
</Grid.Row>
{appContext.state.notification?.isVisible && (
<Grid.Row>
<Grid.Column>
<MessageBar
messageBarType={appContext.state.notification?.messageBarType}
isMultiline={appContext.state.notification?.isMultiline}
onDismiss={onDismissMessageBar}
>
{appContext.state.notification?.message}
</MessageBar>
</Grid.Column>
</Grid.Row>
)}
<Grid.Row>
<Grid.Column>
{loading && (
<Loader size='massive' active={loading}>
Loading...
</Loader>
)}
{!loading && (
<Table selectable>
<Table.Header>
<Table.Row>
{columns.map((column: string, index: number) => {
return (
<Table.HeaderCell key={index}>{column}</Table.HeaderCell>
);
})}
</Table.Row>
</Table.Header>
<Table.Body>
{state.items.map((item) => {
return (
<Table.Row key={item.id}>
<Table.Cell>{item.name}</Table.Cell>
<Table.Cell textAlign='right'>
<Button basic icon onClick={() => onDetails(item.id)}>
<Icon name='info circle' />
</Button>
</Table.Cell>
</Table.Row>
);
})}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan='2'>
<Grid columns={1}>
<Grid.Row>
<Grid.Column textAlign='right'>
<Pagination
totalPages={pagination ? pagination.TotalPages : ''}
activePage={state.currentPageNumber}
onPageChange={onPageChange}
size='mini'
/>
</Grid.Column>
</Grid.Row>
</Grid>
</Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
)}
</Grid.Column>
</Grid.Row>
</Grid>
);
};
export default Sports;

View File

@@ -0,0 +1,50 @@
import { ISportsState } from './ISportsState';
import { ISport } from '../../models/ISport';
export type Action =
| { type: 'SET_ITEMS'; payload: ISport[] }
| { type: 'SET_CURRENT_PAGE_NUMBER'; payload: number }
| { type: 'SET_PAGE_SIZE'; payload: number }
| { type: 'SET_IS_PANEL_OPEN'; payload: boolean };
export const initialState: ISportsState = {
items: [],
currentPageNumber: 1,
pageSize: 10,
isPanelOpen: false
};
export const reducer = (
state: ISportsState,
action: Action
): ISportsState => {
switch (action.type) {
case 'SET_ITEMS': {
return {
...state,
items: action.payload
};
}
case 'SET_CURRENT_PAGE_NUMBER': {
return {
...state,
currentPageNumber: action.payload
};
}
case 'SET_PAGE_SIZE': {
return {
...state,
pageSize: action.payload
};
}
case 'SET_IS_PANEL_OPEN': {
return {
...state,
isPanelOpen: action.payload
};
}
default: {
return state;
}
}
};

View File

@@ -1,13 +1,9 @@
import { ICommandBarItemProps } from "@fluentui/react/lib/CommandBar";
import { ICommandBarItemProps } from '@fluentui/react/lib/CommandBar';
import { ITeam } from '../../models/ITeam';
export interface ITeamsState {
items: ITeam[];
totalItemCount: number | null;
totalPageCount: number | null;
currentPageNumber: number;
pageSize: number;
selectedItems: ITeam[];
commandBarItems: ICommandBarItemProps[];
isPanelOpen: boolean;
}
items: ITeam[];
currentPageNumber: number;
pageSize: number;
isPanelOpen: boolean;
}

View File

@@ -1,135 +1,124 @@
import React, { SyntheticEvent, useEffect, useReducer } from 'react';
import { useQuery } from '@apollo/client';
import { MessageBar, MessageBarType } from '@fluentui/react/lib/MessageBar';
import { initialState, reducer } from './reducer'
import { initialState, reducer } from './reducer';
import { useAppContext } from '../../hooks/appContext/UseAppContext';
import { useSidebarContext } from '../../hooks/sidebarContext/UseSidebarContext';
import { GET_TEAMS } from '../../constants/graphQL';
import { INotification } from '../../models/INotification';
import { Button, Grid, Header, Icon, Loader, Pagination, Table } from 'semantic-ui-react'
import {
Button,
Grid,
Header,
Icon,
Loader,
Pagination,
Table
} from 'semantic-ui-react';
import { usePagination } from '../../hooks/usePaginiation/UsePagination';
const Teams: React.FC<unknown> = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const appContext = useAppContext();
const sidebarContext = useSidebarContext();
const currentPageNumber = state.currentPageNumber;
const pageSize = state.pageSize;
const { data, loading, error, refetch } = useQuery(GET_TEAMS, {
variables: {
pageNumber: currentPageNumber,
pageSize: pageSize
}
})
const columns: string[] = [
'Name',
''
]
const onPageChange = (event: SyntheticEvent, data: any) => {
const newCurrentPage: number = data.activePage;
dispatch({ type: 'SET_CURRENT_PAGE_NUMBER', payload: newCurrentPage });
const [state, dispatch] = useReducer(reducer, initialState);
const appContext = useAppContext();
const sidebarContext = useSidebarContext();
const currentPageNumber = state.currentPageNumber;
const pageSize = state.pageSize;
const { data, loading, error, refetch } = useQuery(GET_TEAMS, {
variables: {
pageNumber: currentPageNumber,
pageSize: pageSize
}
});
const { pagination } = usePagination();
useEffect(() => {
if (data) {
dispatch({
type: 'SET_ITEMS',
payload: {
items: data.teams.results,
totalItemCount: data.teams.totalItemCount,
totalPageCount: data.teams.totalPageCount
}
})
}
}, [data])
const columns: string[] = ['Name', ''];
useEffect(() => {
refetch({
pageNumber: currentPageNumber,
pageSize: pageSize
})
}, [currentPageNumber])
const onPageChange = (event: SyntheticEvent, data: any) => {
const newCurrentPage: number = data.activePage;
return (
<Grid columns={1}>
<Grid.Row>
<Header as='h1'>
Teams
</Header>
</Grid.Row>
{appContext.state.notification?.isVisible && (
<Grid.Row>
<Grid.Column>
</Grid.Column>
</Grid.Row>
)}
<Grid.Row>
<Grid.Column>
{loading && (
<Loader size='massive' active={loading}>Loading...</Loader>
)}
{!loading &&
<Table selectable>
<Table.Header>
<Table.Row>
{columns.map((column: string) => {
return (
<Table.HeaderCell>
{column}
</Table.HeaderCell>
)
})}
</Table.Row>
</Table.Header>
<Table.Body>
{state.items.map((item) => {
return (
<Table.Row
key={item.id}
>
<Table.Cell>
{item.name}
</Table.Cell>
<Table.Cell textAlign='right'>
<Button
basic
icon
// onClick={() => onDetails(item.id)}
>
<Icon name='info circle' />
</Button>
</Table.Cell>
</Table.Row>
)
})}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan='2'>
<Grid columns={1}>
<Grid.Row>
<Grid.Column textAlign='right'>
<Pagination
totalPages={data.teams.totalPageCount}
activePage={state.currentPageNumber}
onPageChange={onPageChange}
size='mini'
/>
</Grid.Column>
</Grid.Row>
</Grid>
</Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
}
</Grid.Column>
</Grid.Row>
</Grid>
)
}
dispatch({ type: 'SET_CURRENT_PAGE_NUMBER', payload: newCurrentPage });
};
export default Teams;
useEffect(() => {
if (data) {
dispatch({ type: 'SET_ITEMS', payload: data.teams });
}
}, [data]);
useEffect(() => {
refetch({
pageNumber: currentPageNumber,
pageSize: pageSize
});
}, [currentPageNumber]);
return (
<Grid columns={1}>
<Grid.Row>
<Header as='h1'>Teams</Header>
</Grid.Row>
{appContext.state.notification?.isVisible && (
<Grid.Row>
<Grid.Column></Grid.Column>
</Grid.Row>
)}
<Grid.Row>
<Grid.Column>
{loading && (
<Loader size='massive' active={loading}>
Loading...
</Loader>
)}
{!loading && (
<Table selectable>
<Table.Header>
<Table.Row>
{columns.map((column: string) => {
return <Table.HeaderCell>{column}</Table.HeaderCell>;
})}
</Table.Row>
</Table.Header>
<Table.Body>
{state.items.map((item) => {
return (
<Table.Row key={item.id}>
<Table.Cell>{item.name}</Table.Cell>
<Table.Cell textAlign='right'>
<Button
basic
icon
// onClick={() => onDetails(item.id)}
>
<Icon name='info circle' />
</Button>
</Table.Cell>
</Table.Row>
);
})}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan='2'>
<Grid columns={1}>
<Grid.Row>
<Grid.Column textAlign='right'>
<Pagination
totalPages={pagination ? pagination.TotalPages : ''}
activePage={state.currentPageNumber}
onPageChange={onPageChange}
size='mini'
/>
</Grid.Column>
</Grid.Row>
</Grid>
</Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
)}
</Grid.Column>
</Grid.Row>
</Grid>
);
};
export default Teams;

View File

@@ -1,73 +1,47 @@
import { ITeamsState } from './ITeamsState';
import { ITeam } from '../../models/ITeam';
import { ICommandBarItemProps } from '@fluentui/react/lib/CommandBar';
import { IObjectWithKey } from '@fluentui/react';
export type Action =
| {
type: 'SET_ITEMS';
payload: {
items: ITeam[];
totalItemCount: number;
totalPageCount: number;
};
}
| { type: 'SET_CURRENT_PAGE_NUMBER'; payload: number }
| { type: 'SET_PAGE_SIZE'; payload: number }
| { type: 'SET_SELECTED_ITEM'; payload: IObjectWithKey[] }
| { type: 'SET_COMMAND_BAR_ITEMS'; payload: ICommandBarItemProps[] }
| { type: 'SET_IS_PANEL_OPEN'; payload: boolean };
| { type: 'SET_ITEMS'; payload: ITeam[] }
| { type: 'SET_CURRENT_PAGE_NUMBER'; payload: number }
| { type: 'SET_PAGE_SIZE'; payload: number }
| { type: 'SET_IS_PANEL_OPEN'; payload: boolean };
export const initialState: ITeamsState = {
items: [],
totalItemCount: null,
totalPageCount: null,
currentPageNumber: 1,
pageSize: 10,
selectedItems: [],
commandBarItems: [],
isPanelOpen: false
}
items: [],
currentPageNumber: 1,
pageSize: 10,
isPanelOpen: false
};
export const reducer = (state: ITeamsState, action: Action): ITeamsState => {
switch (action.type) {
case 'SET_ITEMS': {
return {
...state,
items: action.payload.items,
totalItemCount: action.payload.totalItemCount,
totalPageCount: action.payload.totalPageCount
};
}
case 'SET_CURRENT_PAGE_NUMBER': {
return {
...state,
currentPageNumber: action.payload
};
}
case 'SET_PAGE_SIZE': {
return {
...state,
pageSize: action.payload
};
}
case 'SET_SELECTED_ITEM': {
return {
...state,
selectedItems: <ITeam[]>action.payload
};
}
case 'SET_COMMAND_BAR_ITEMS': {
return {
...state,
commandBarItems: action.payload
};
}
case 'SET_IS_PANEL_OPEN': {
return {
...state,
isPanelOpen: action.payload
};
}
switch (action.type) {
case 'SET_ITEMS': {
return {
...state,
items: action.payload
};
}
}
case 'SET_CURRENT_PAGE_NUMBER': {
return {
...state,
currentPageNumber: action.payload
};
}
case 'SET_PAGE_SIZE': {
return {
...state,
pageSize: action.payload
};
}
case 'SET_IS_PANEL_OPEN': {
return {
...state,
isPanelOpen: action.payload
};
}
default: {
return state;
}
}
};

View File

@@ -1,3 +1,3 @@
export interface IVenueDetailsProps {
venueId: number;
}
venueId: number;
}

View File

@@ -2,32 +2,32 @@ import React, { useEffect } from 'react';
import { IVenueDetailsProps } from './IVenueDetailsProps';
import { Grid, Header } from 'semantic-ui-react';
import { useQuery } from '@apollo/client';
import { GET_VENUE_BY_ID } from '../../constants/graphQL';
import { GET_VENUE } from '../../constants/graphQL';
const VenueDetails: React.FC<IVenueDetailsProps> = ({ venueId }: IVenueDetailsProps) => {
const { data, loading, error } = useQuery(GET_VENUE_BY_ID, {
variables: {
id: venueId
}
});
const VenueDetails: React.FC<IVenueDetailsProps> = ({
venueId
}: IVenueDetailsProps) => {
const { data, loading, error } = useQuery(GET_VENUE, {
variables: {
id: venueId
}
});
return (
<Grid>
<Grid.Row>
<Header as='h2'>
Venue
</Header>
</Grid.Row>
<Grid.Row>
{data &&
<ul>
<li>{data.venueById.results.name}</li>
<li>{data.venueById.results.id}</li>
</ul>
}
</Grid.Row>
</Grid>
)
}
return (
<Grid>
<Grid.Row>
<Header as='h2'>Venue</Header>
</Grid.Row>
<Grid.Row>
{data && (
<ul>
<li>{data.venueById.results.name}</li>
<li>{data.venueById.results.id}</li>
</ul>
)}
</Grid.Row>
</Grid>
);
};
export default VenueDetails;
export default VenueDetails;

View File

@@ -1,13 +1,8 @@
import { ICommandBarItemProps } from '@fluentui/react/lib/CommandBar';
import { IVenue } from '../../models/IVenue';
export interface IVenuesState {
items: IVenue[];
totalItemCount: number | null;
totalPageCount: number | null;
currentPageNumber: number;
pageSize: number;
selectedItems: IVenue[];
commandBarItems: ICommandBarItemProps[];
isPanelOpen: boolean;
}

View File

@@ -6,8 +6,18 @@ import { useAppContext } from '../../hooks/appContext/UseAppContext';
import { useSidebarContext } from '../../hooks/sidebarContext/UseSidebarContext';
import { GET_VENUES } from '../../constants/graphQL';
import { INotification } from '../../models/INotification';
import { Button, Grid, Header, Icon, Loader, Pagination, Sidebar, Table } from 'semantic-ui-react';
import {
Button,
Grid,
Header,
Icon,
Loader,
Pagination,
Sidebar,
Table
} from 'semantic-ui-react';
import VenueDetails from '../venueDetails/VenueDetails';
import { usePagination } from '../../hooks/usePaginiation/UsePagination';
const Venues: React.FC<unknown> = () => {
const [state, dispatch] = useReducer(reducer, initialState);
@@ -21,11 +31,9 @@ const Venues: React.FC<unknown> = () => {
pageSize: pageSize
}
});
const { pagination } = usePagination();
const columns: string[] = [
'Name',
''
]
const columns: string[] = ['Name', ''];
const onDismissMessageBar = () => {
const notification: INotification = {
@@ -43,28 +51,31 @@ const Venues: React.FC<unknown> = () => {
};
const onDetails = (id: number) => {
sidebarContext.dispatch({ type: 'SET_SIDEBAR', payload: { sidebar: { visible: true, animation: 'overlay', width: 'very wide', direction: 'right' }, content: <VenueDetails venueId={id} />}})
}
useEffect(() => {
console.log(sidebarContext)
}, [sidebarContext])
sidebarContext.dispatch({
type: 'SET_SIDEBAR',
payload: {
sidebar: {
visible: true,
animation: 'overlay',
width: 'very wide',
direction: 'right'
},
content: <VenueDetails venueId={id} />
}
});
};
useEffect(() => {
if (data) {
dispatch({
type: 'SET_ITEMS',
payload: {
items: data.venues.results,
totalItemCount: data.venues.totalItemCount,
totalPageCount: data.venues.totalPageCount
}
payload: data.venues
});
}
}, [data]);
useEffect(() => {
console.log(error);
// console.log(error);
const notification: INotification = {
messageBarType: MessageBarType.error,
message: error?.message,
@@ -80,66 +91,56 @@ const Venues: React.FC<unknown> = () => {
pageNumber: currentPageNumber,
pageSize: pageSize
});
}, [currentPageNumber])
}, [currentPageNumber]);
return (
<Grid columns={1}>
<Grid.Row>
<Header as='h1'>
Venues
</Header>
<Header as='h1'>Venues</Header>
</Grid.Row>
{appContext.state.notification?.isVisible && (
<Grid.Row>
<Grid.Column>
<MessageBar
messageBarType={appContext.state.notification?.messageBarType}
isMultiline={appContext.state.notification?.isMultiline}
onDismiss={onDismissMessageBar}
>
{appContext.state.notification?.message}
</MessageBar>
<MessageBar
messageBarType={appContext.state.notification?.messageBarType}
isMultiline={appContext.state.notification?.isMultiline}
onDismiss={onDismissMessageBar}
>
{appContext.state.notification?.message}
</MessageBar>
</Grid.Column>
</Grid.Row>
)}
<Grid.Row>
<Grid.Column>
{loading && (
<Loader size='massive' active={loading}>Loading...</Loader>
<Loader size='massive' active={loading}>
Loading...
</Loader>
)}
{!loading &&
{!loading && (
<Table selectable>
<Table.Header>
<Table.Row>
{columns.map((column: string) => {
{columns.map((column: string, index: number) => {
return (
<Table.HeaderCell>
{column}
</Table.HeaderCell>
)
<Table.HeaderCell key={index}>{column}</Table.HeaderCell>
);
})}
</Table.Row>
</Table.Header>
<Table.Body>
{state.items.map((item) => {
return (
<Table.Row
key={item.id}
>
<Table.Cell>
{item.name}
</Table.Cell>
<Table.Row key={item.id}>
<Table.Cell>{item.name}</Table.Cell>
<Table.Cell textAlign='right'>
<Button
basic
icon
onClick={() => onDetails(item.id)}
>
<Button basic icon onClick={() => onDetails(item.id)}>
<Icon name='info circle' />
</Button>
</Table.Cell>
</Table.Row>
)
);
})}
</Table.Body>
<Table.Footer>
@@ -147,11 +148,9 @@ const Venues: React.FC<unknown> = () => {
<Table.HeaderCell colSpan='2'>
<Grid columns={1}>
<Grid.Row>
<Grid.Column
textAlign='right'
>
<Grid.Column textAlign='right'>
<Pagination
totalPages={data?.venues?.totalPageCount}
totalPages={pagination ? pagination.TotalPages : ''}
activePage={state.currentPageNumber}
onPageChange={onPageChange}
size='mini'
@@ -163,7 +162,7 @@ const Venues: React.FC<unknown> = () => {
</Table.Row>
</Table.Footer>
</Table>
}
)}
</Grid.Column>
</Grid.Row>
</Grid>

View File

@@ -1,31 +1,16 @@
import { IVenuesState } from './IVenuesState';
import { IVenue } from '../../models/IVenue';
import { ICommandBarItemProps } from '@fluentui/react/lib/CommandBar';
import { IObjectWithKey } from '@fluentui/react';
export type Action =
| {
type: 'SET_ITEMS';
payload: {
items: IVenue[];
totalItemCount: number;
totalPageCount: number;
};
}
| { type: 'SET_ITEMS'; payload: IVenue[] }
| { type: 'SET_CURRENT_PAGE_NUMBER'; payload: number }
| { type: 'SET_PAGE_SIZE'; payload: number }
| { type: 'SET_SELECTED_ITEM'; payload: IObjectWithKey[] }
| { type: 'SET_COMMAND_BAR_ITEMS'; payload: ICommandBarItemProps[] }
| { type: 'SET_IS_PANEL_OPEN'; payload: boolean };
export const initialState: IVenuesState = {
items: [],
totalItemCount: null,
totalPageCount: null,
currentPageNumber: 1,
pageSize: 10,
selectedItems: [],
commandBarItems: [],
isPanelOpen: false
};
@@ -34,9 +19,7 @@ export const reducer = (state: IVenuesState, action: Action): IVenuesState => {
case 'SET_ITEMS': {
return {
...state,
items: action.payload.items,
totalItemCount: action.payload.totalItemCount,
totalPageCount: action.payload.totalPageCount
items: action.payload
};
}
case 'SET_CURRENT_PAGE_NUMBER': {
@@ -51,23 +34,14 @@ export const reducer = (state: IVenuesState, action: Action): IVenuesState => {
pageSize: action.payload
};
}
case 'SET_SELECTED_ITEM': {
return {
...state,
selectedItems: <IVenue[]>action.payload
};
}
case 'SET_COMMAND_BAR_ITEMS': {
return {
...state,
commandBarItems: action.payload
};
}
case 'SET_IS_PANEL_OPEN': {
return {
...state,
isPanelOpen: action.payload
};
}
default: {
return state;
}
}
};