diff --git a/client/src/components/UI/Buttons/ActionButton/ActionButton.tsx b/client/src/components/UI/Buttons/ActionButton/ActionButton.tsx index 3e99935..8100271 100644 --- a/client/src/components/UI/Buttons/ActionButton/ActionButton.tsx +++ b/client/src/components/UI/Buttons/ActionButton/ActionButton.tsx @@ -2,55 +2,45 @@ import { Fragment } from 'react'; import { Link } from 'react-router-dom'; import classes from './ActionButton.module.css'; -import Icon from '../../Icons/Icon/Icon'; +import { Icon } from '../..'; -interface ComponentProps { +interface Props { name: string; icon: string; link?: string; handler?: () => void; } -const ActionButton = (props: ComponentProps): JSX.Element => { +export const ActionButton = (props: Props): JSX.Element => { const body = (
-
- {props.name} -
+
{props.name}
); if (props.link) { return ( - + {body} - ) + ); } else if (props.handler) { return (
{ - if (e.key === 'Enter' && props.handler) props.handler() + if (e.key === 'Enter' && props.handler) props.handler(); }} tabIndex={0} - >{body} -
- ) - } else { - return ( -
+ > {body}
- ) + ); + } else { + return
{body}
; } -} - -export default ActionButton; \ No newline at end of file +}; diff --git a/client/src/components/UI/Buttons/Button/Button.tsx b/client/src/components/UI/Buttons/Button/Button.tsx index 5f113d8..5e9e9d5 100644 --- a/client/src/components/UI/Buttons/Button/Button.tsx +++ b/client/src/components/UI/Buttons/Button/Button.tsx @@ -1,21 +1,16 @@ import classes from './Button.module.css'; -interface ComponentProps { +interface Props { children: string; click?: any; } -const Button = (props: ComponentProps): JSX.Element => { - const { - children, - click - } = props; +export const Button = (props: Props): JSX.Element => { + const { children, click } = props; return ( - - ) -} - -export default Button; \ No newline at end of file + ); +}; diff --git a/client/src/components/UI/Forms/InputGroup/InputGroup.tsx b/client/src/components/UI/Forms/InputGroup/InputGroup.tsx index d39f139..409af27 100644 --- a/client/src/components/UI/Forms/InputGroup/InputGroup.tsx +++ b/client/src/components/UI/Forms/InputGroup/InputGroup.tsx @@ -1,15 +1,10 @@ +import { ReactNode } from 'react'; import classes from './InputGroup.module.css'; -interface ComponentProps { - children: JSX.Element | JSX.Element[]; +interface Props { + children: ReactNode; } -const InputGroup = (props: ComponentProps): JSX.Element => { - return ( -
- {props.children} -
- ) -} - -export default InputGroup; \ No newline at end of file +export const InputGroup = (props: Props): JSX.Element => { + return
{props.children}
; +}; diff --git a/client/src/components/UI/Forms/ModalForm/ModalForm.tsx b/client/src/components/UI/Forms/ModalForm/ModalForm.tsx index 7ab2eac..0db23b5 100644 --- a/client/src/components/UI/Forms/ModalForm/ModalForm.tsx +++ b/client/src/components/UI/Forms/ModalForm/ModalForm.tsx @@ -1,31 +1,27 @@ -import { SyntheticEvent } from 'react'; +import { ReactNode, SyntheticEvent } from 'react'; import classes from './ModalForm.module.css'; -import Icon from '../../Icons/Icon/Icon'; +import { Icon } from '../..'; interface ComponentProps { - children: JSX.Element | JSX.Element[]; + children: ReactNode; modalHandler?: () => void; formHandler: (e: SyntheticEvent) => void; } -const ModalForm = (props: ComponentProps): JSX.Element => { +export const ModalForm = (props: ComponentProps): JSX.Element => { const _modalHandler = (): void => { if (props.modalHandler) { props.modalHandler(); } - } + }; return (
- +
-
props.formHandler(e)}> - {props.children} -
+
props.formHandler(e)}>{props.children}
- ) -} - -export default ModalForm; \ No newline at end of file + ); +}; diff --git a/client/src/components/UI/Headlines/Headline/Headline.tsx b/client/src/components/UI/Headlines/Headline/Headline.tsx index bb70b65..8178e5e 100644 --- a/client/src/components/UI/Headlines/Headline/Headline.tsx +++ b/client/src/components/UI/Headlines/Headline/Headline.tsx @@ -1,18 +1,18 @@ -import { Fragment } from 'react'; +import { Fragment, ReactNode } from 'react'; import classes from './Headline.module.css'; -interface ComponentProps { +interface Props { title: string; - subtitle?: string | JSX.Element; + subtitle?: ReactNode; } -const Headline = (props: ComponentProps): JSX.Element => { +export const Headline = (props: Props): JSX.Element => { return (

{props.title}

- {props.subtitle &&

{props.subtitle}

} + {props.subtitle && ( +

{props.subtitle}

+ )}
- ) -} - -export default Headline; \ No newline at end of file + ); +}; diff --git a/client/src/components/UI/Headlines/SectionHeadline/SectionHeadline.tsx b/client/src/components/UI/Headlines/SectionHeadline/SectionHeadline.tsx index 8fd2a19..474dd52 100644 --- a/client/src/components/UI/Headlines/SectionHeadline/SectionHeadline.tsx +++ b/client/src/components/UI/Headlines/SectionHeadline/SectionHeadline.tsx @@ -2,17 +2,15 @@ import { Link } from 'react-router-dom'; import classes from './SectionHeadline.module.css'; -interface ComponentProps { +interface Props { title: string; - link: string + link: string; } -const SectionHeadline = (props: ComponentProps): JSX.Element => { +export const SectionHeadline = (props: Props): JSX.Element => { return (

{props.title}

- ) -} - -export default SectionHeadline; \ No newline at end of file + ); +}; diff --git a/client/src/components/UI/Headlines/SettingsHeadline/SettingsHeadline.tsx b/client/src/components/UI/Headlines/SettingsHeadline/SettingsHeadline.tsx index 5d14949..b3a005e 100644 --- a/client/src/components/UI/Headlines/SettingsHeadline/SettingsHeadline.tsx +++ b/client/src/components/UI/Headlines/SettingsHeadline/SettingsHeadline.tsx @@ -4,8 +4,6 @@ interface Props { text: string; } -const SettingsHeadline = (props: Props): JSX.Element => { +export const SettingsHeadline = (props: Props): JSX.Element => { return

{props.text}

; }; - -export default SettingsHeadline; diff --git a/client/src/components/UI/Icons/Icon/Icon.module.css b/client/src/components/UI/Icons/Icon/Icon.module.css index 33b3aa7..ffc847e 100644 --- a/client/src/components/UI/Icons/Icon/Icon.module.css +++ b/client/src/components/UI/Icons/Icon/Icon.module.css @@ -1,6 +1,4 @@ .Icon { color: var(--color-primary); - /* for settings */ - /* color: var(--color-background); */ width: 90%; -} \ No newline at end of file +} diff --git a/client/src/components/UI/Icons/Icon/Icon.tsx b/client/src/components/UI/Icons/Icon/Icon.tsx index 6924086..50da4d8 100644 --- a/client/src/components/UI/Icons/Icon/Icon.tsx +++ b/client/src/components/UI/Icons/Icon/Icon.tsx @@ -2,12 +2,12 @@ import classes from './Icon.module.css'; import { Icon as MDIcon } from '@mdi/react'; -interface ComponentProps { +interface Props { icon: string; color?: string; } -const Icon = (props: ComponentProps): JSX.Element => { +export const Icon = (props: Props): JSX.Element => { const MDIcons = require('@mdi/js'); let iconPath = MDIcons[props.icon]; @@ -22,7 +22,5 @@ const Icon = (props: ComponentProps): JSX.Element => { path={iconPath} color={props.color ? props.color : 'var(--color-primary)'} /> - ) -} - -export default Icon; \ No newline at end of file + ); +}; diff --git a/client/src/components/UI/Icons/WeatherIcon/WeatherIcon.tsx b/client/src/components/UI/Icons/WeatherIcon/WeatherIcon.tsx index 111967e..2664b47 100644 --- a/client/src/components/UI/Icons/WeatherIcon/WeatherIcon.tsx +++ b/client/src/components/UI/Icons/WeatherIcon/WeatherIcon.tsx @@ -1,39 +1,32 @@ import { useEffect } from 'react'; -import { connect } from 'react-redux'; +import { useSelector } from 'react-redux'; import { Skycons } from 'skycons-ts'; -import { GlobalState, Theme } from '../../../../interfaces'; +import { State } from '../../../../store/reducers'; import { IconMapping, TimeOfDay } from './IconMapping'; -interface ComponentProps { - theme: Theme; +interface Props { weatherStatusCode: number; isDay: number; } -const WeatherIcon = (props: ComponentProps): JSX.Element => { +export const WeatherIcon = (props: Props): JSX.Element => { + const { theme } = useSelector((state: State) => state.theme); + const icon = props.isDay ? new IconMapping().mapIcon(props.weatherStatusCode, TimeOfDay.day) : new IconMapping().mapIcon(props.weatherStatusCode, TimeOfDay.night); useEffect(() => { const delay = setTimeout(() => { - const skycons = new Skycons({'color': props.theme.colors.accent}); + const skycons = new Skycons({ color: theme.colors.accent }); skycons.add(`weather-icon`, icon); skycons.play(); }, 1); return () => { clearTimeout(delay); - } - }, [props.weatherStatusCode, icon, props.theme.colors.accent]); + }; + }, [props.weatherStatusCode, icon, theme.colors.accent]); - return -} - -const mapStateToProps = (state: GlobalState) => { - return { - theme: state.theme.theme - } -} - -export default connect(mapStateToProps)(WeatherIcon); \ No newline at end of file + return ; +}; diff --git a/client/src/components/UI/Layout/Layout.tsx b/client/src/components/UI/Layout/Layout.tsx index b7fe50f..8588ef1 100644 --- a/client/src/components/UI/Layout/Layout.tsx +++ b/client/src/components/UI/Layout/Layout.tsx @@ -1,13 +1,10 @@ +import { ReactNode } from 'react'; import classes from './Layout.module.css'; interface ComponentProps { - children: JSX.Element | JSX.Element[]; + children: ReactNode; } export const Container = (props: ComponentProps): JSX.Element => { - return ( -
- {props.children} -
- ) -} \ No newline at end of file + return
{props.children}
; +}; diff --git a/client/src/components/UI/Modal/Modal.tsx b/client/src/components/UI/Modal/Modal.tsx index ccb82be..43fb5e9 100644 --- a/client/src/components/UI/Modal/Modal.tsx +++ b/client/src/components/UI/Modal/Modal.tsx @@ -1,28 +1,29 @@ -import { MouseEvent, useRef } from 'react'; +import { MouseEvent, ReactNode, useRef } from 'react'; import classes from './Modal.module.css'; -interface ComponentProps { +interface Props { isOpen: boolean; setIsOpen: Function; - children: JSX.Element; + children: ReactNode; } -const Modal = (props: ComponentProps): JSX.Element => { +export const Modal = (props: Props): JSX.Element => { const modalRef = useRef(null); - const modalClasses = [classes.Modal, props.isOpen ? classes.ModalOpen : classes.ModalClose].join(' '); + const modalClasses = [ + classes.Modal, + props.isOpen ? classes.ModalOpen : classes.ModalClose, + ].join(' '); const clickHandler = (e: MouseEvent) => { if (e.target === modalRef.current) { props.setIsOpen(false); } - } + }; return (
{props.children}
- ) -} - -export default Modal; \ No newline at end of file + ); +}; diff --git a/client/src/components/UI/Notification/Notification.tsx b/client/src/components/UI/Notification/Notification.tsx index 2bd5185..c03be54 100644 --- a/client/src/components/UI/Notification/Notification.tsx +++ b/client/src/components/UI/Notification/Notification.tsx @@ -1,18 +1,21 @@ import { useEffect, useState } from 'react'; -import { connect } from 'react-redux'; -import { clearNotification } from '../../../store/actions'; +import { useDispatch } from 'react-redux'; +import { bindActionCreators } from 'redux'; +import { actionCreators } from '../../../store'; import classes from './Notification.module.css'; -interface ComponentProps { +interface Props { title: string; message: string; id: number; url: string | null; - clearNotification: (id: number) => void; } -const Notification = (props: ComponentProps): JSX.Element => { +export const Notification = (props: Props): JSX.Element => { + const dispatch = useDispatch(); + const { clearNotification } = bindActionCreators(actionCreators, dispatch); + const [isOpen, setIsOpen] = useState(true); const elementClasses = [ classes.Notification, @@ -24,13 +27,13 @@ const Notification = (props: ComponentProps): JSX.Element => { setIsOpen(false); }, 3500); - const clearNotification = setTimeout(() => { - props.clearNotification(props.id); + const clearNotificationTimeout = setTimeout(() => { + clearNotification(props.id); }, 3600); return () => { window.clearTimeout(closeNotification); - window.clearTimeout(clearNotification); + window.clearTimeout(clearNotificationTimeout); }; }, []); @@ -48,5 +51,3 @@ const Notification = (props: ComponentProps): JSX.Element => { ); }; - -export default connect(null, { clearNotification })(Notification); diff --git a/client/src/components/UI/Spinner/Spinner.tsx b/client/src/components/UI/Spinner/Spinner.tsx index a081c51..c5abb2c 100644 --- a/client/src/components/UI/Spinner/Spinner.tsx +++ b/client/src/components/UI/Spinner/Spinner.tsx @@ -1,11 +1,9 @@ import classes from './Spinner.module.css'; -const Spinner = (): JSX.Element => { +export const Spinner = (): JSX.Element => { return (
Loading...
- ) -} - -export default Spinner; \ No newline at end of file + ); +}; diff --git a/client/src/components/UI/Table/Table.tsx b/client/src/components/UI/Table/Table.tsx index d425dc1..43c4305 100644 --- a/client/src/components/UI/Table/Table.tsx +++ b/client/src/components/UI/Table/Table.tsx @@ -1,26 +1,26 @@ import classes from './Table.module.css'; -interface ComponentProps { - children: JSX.Element | JSX.Element[]; +interface Props { + children: React.ReactNode; headers: string[]; innerRef?: any; } -const Table = (props: ComponentProps): JSX.Element => { +export const Table = (props: Props): JSX.Element => { return (
- {props.headers.map((header: string, index: number): JSX.Element => ())} + {props.headers.map( + (header: string, index: number): JSX.Element => ( + + ) + )} - - {props.children} - + {props.children}
{header}{header}
- ) -} - -export default Table; \ No newline at end of file + ); +}; diff --git a/client/src/components/UI/index.ts b/client/src/components/UI/index.ts new file mode 100644 index 0000000..e1c0917 --- /dev/null +++ b/client/src/components/UI/index.ts @@ -0,0 +1,14 @@ +export * from './Table/Table'; +export * from './Spinner/Spinner'; +export * from './Notification/Notification'; +export * from './Modal/Modal'; +export * from './Layout/Layout'; +export * from './Icons/Icon/Icon'; +export * from './Icons/WeatherIcon/WeatherIcon'; +export * from './Headlines/Headline/Headline'; +export * from './Headlines/SectionHeadline/SectionHeadline'; +export * from './Headlines/SettingsHeadline/SettingsHeadline'; +export * from './Forms/InputGroup/InputGroup'; +export * from './Forms/ModalForm/ModalForm'; +export * from './Buttons/ActionButton/ActionButton'; +export * from './Buttons/Button/Button';