Major update
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
.content {
|
||||
padding: 30px;
|
||||
}
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
171
app/src/components/divisions/Divisions.tsx
Normal file
171
app/src/components/divisions/Divisions.tsx
Normal 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;
|
||||
8
app/src/components/divisions/IDivisionsState.ts
Normal file
8
app/src/components/divisions/IDivisionsState.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { IDivision } from '../../models/IDivision';
|
||||
|
||||
export interface IDivisionsState {
|
||||
items: IDivision[];
|
||||
currentPageNumber: number;
|
||||
pageSize: number;
|
||||
isPanelOpen: boolean;
|
||||
}
|
||||
50
app/src/components/divisions/reducer.ts
Normal file
50
app/src/components/divisions/reducer.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
.siteFooter {
|
||||
background-color: #e0e1e2;
|
||||
height: 150px;
|
||||
}
|
||||
background-color: #e0e1e2;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.siteHeader {
|
||||
background-color: #e0e1e2;
|
||||
height: 100px;
|
||||
}
|
||||
background-color: #e0e1e2;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
8
app/src/components/leagues/ILeaguesState.ts
Normal file
8
app/src/components/leagues/ILeaguesState.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { ILeague } from '../../models/ILeague';
|
||||
|
||||
export interface ILeaguesState {
|
||||
items: ILeague[];
|
||||
currentPageNumber: number;
|
||||
pageSize: number;
|
||||
isPanelOpen: boolean;
|
||||
}
|
||||
173
app/src/components/leagues/Leagues.tsx
Normal file
173
app/src/components/leagues/Leagues.tsx
Normal 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;
|
||||
50
app/src/components/leagues/reducer.ts
Normal file
50
app/src/components/leagues/reducer.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface INewSeasonModalProps {
|
||||
isModalOpen: boolean;
|
||||
onCloseModal: () => void;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { HubConnection } from "@microsoft/signalr";
|
||||
|
||||
export interface INewSeasonModalState {
|
||||
connection: HubConnection | undefined,
|
||||
year: string;
|
||||
percentComplete: number;
|
||||
loading: boolean;
|
||||
}
|
||||
134
app/src/components/newSeasonDialog/NewSeasonModal.tsx
Normal file
134
app/src/components/newSeasonDialog/NewSeasonModal.tsx
Normal 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;
|
||||
47
app/src/components/newSeasonDialog/reducer.ts
Normal file
47
app/src/components/newSeasonDialog/reducer.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) => {
|
||||
|
||||
9
app/src/components/seasons/ISeasonsState.ts
Normal file
9
app/src/components/seasons/ISeasonsState.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { ISeason } from '../../models/ISeason';
|
||||
|
||||
export interface ISeasonsState {
|
||||
items: ISeason[];
|
||||
currentPageNumber: number;
|
||||
pageSize: number;
|
||||
isPanelOpen: boolean;
|
||||
isModalOpen: boolean;
|
||||
}
|
||||
202
app/src/components/seasons/Seasons.tsx
Normal file
202
app/src/components/seasons/Seasons.tsx
Normal 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;
|
||||
58
app/src/components/seasons/reducer.ts
Normal file
58
app/src/components/seasons/reducer.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
8
app/src/components/sports/ISportsState.ts
Normal file
8
app/src/components/sports/ISportsState.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { ISport } from '../../models/ISport';
|
||||
|
||||
export interface ISportsState {
|
||||
items: ISport[];
|
||||
currentPageNumber: number;
|
||||
pageSize: number;
|
||||
isPanelOpen: boolean;
|
||||
}
|
||||
172
app/src/components/sports/Sports.tsx
Normal file
172
app/src/components/sports/Sports.tsx
Normal 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;
|
||||
50
app/src/components/sports/reducer.ts
Normal file
50
app/src/components/sports/reducer.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export interface IVenueDetailsProps {
|
||||
venueId: number;
|
||||
}
|
||||
venueId: number;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user