From c8810215324db1f59254354161ad033ae4a2d849 Mon Sep 17 00:00:00 2001 From: Dejvino Date: Sat, 27 May 2023 06:54:35 +0200 Subject: [PATCH] useSize hook for Accordion on small screens --- src/app/components/JobHistory.tsx | 96 +++++++++++++++++++++++-------- src/app/globals.css | 3 +- src/app/hooks/Size.tsx | 30 ++++++++++ src/app/page.tsx | 3 +- 4 files changed, 106 insertions(+), 26 deletions(-) create mode 100644 src/app/hooks/Size.tsx diff --git a/src/app/components/JobHistory.tsx b/src/app/components/JobHistory.tsx index f56f340..26e8d3b 100644 --- a/src/app/components/JobHistory.tsx +++ b/src/app/components/JobHistory.tsx @@ -5,42 +5,90 @@ import Col from 'react-bootstrap/Col'; import Row from 'react-bootstrap/Row'; import JobCard from './JobCard'; import { partition } from '../utils'; -import { Jobs } from '@/PersonalDataTypes'; +import { Job, Jobs } from '@/PersonalDataTypes'; +import useSize from '../hooks/Size'; +import { Accordion } from 'react-bootstrap'; -export type Props = { +type JobListProps = { jobs: Jobs, - heading: string, entriesPerRow?: number, currentHeading?: string, } +export type Props = { + heading: string, +} & JobListProps + const defaultProps = { entriesPerRow: 2, currentHeading: 'Currently', } +function FullList(props: JobListProps) { + const {jobs} = props + const config = {...defaultProps, ...props} + return ( + + {jobs.current && ( + + + + + + )} + {partition(jobs.previous, config.entriesPerRow).map((jobs, index) => ( + + {(jobs.map((job, subindex) => ( + + + + )))} + + ))} + + ) +} + +function SmallList(props: JobListProps) { + const {jobs} = props + const config = {...defaultProps, ...props} + function jobTitle(job: Job) { + return `${job.position} at ${job.company}, ${job.timerange}` + } + return ( + + {jobs.current && ( + + {config.currentHeading}:
{jobTitle(jobs.current)}
+ + {jobs.current.position} + +
+ )} + {jobs.previous?.map((job, index) => ( + + {jobTitle(job)} + + {job.description} + + + ))} +
+ ) +} + export default function JobHistory(props: Props) { - const jobs = props.jobs - const config = {...defaultProps, ...props} - return ( + const {SizeWrapper, size} = useSize() + const jobs = props.jobs + + const jobsList = size.width < 600 ? : + + return ( -

{config.heading}

- {jobs.current && ( - - - - - - )} - {partition(jobs.previous, config.entriesPerRow).map((jobs, index) => ( - - {(jobs.map((job, subindex) => ( - - - - )))} - - ))} +

{props.heading}

+ + {jobsList} +
- ) + ) } diff --git a/src/app/globals.css b/src/app/globals.css index e318ef8..d5ac303 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -17,7 +17,8 @@ body { .tiny { font-size: 75%; } -h2, h3, h4 { + +.container > h2, h3, h4 { margin-top: 1em; } diff --git a/src/app/hooks/Size.tsx b/src/app/hooks/Size.tsx new file mode 100644 index 0000000..58f23c6 --- /dev/null +++ b/src/app/hooks/Size.tsx @@ -0,0 +1,30 @@ +import React, { ForwardedRef, ReactNode, forwardRef, useEffect, useLayoutEffect, useRef, useState } from "react"; + +export default function useSize() { + const areaRef = useRef(null) + const [size, setSize] = useState({ width: 0, height: 0 }) + + function SizeWrapper(props: {children: ReactNode }) { + return ( +
{props.children}
+ ) + } + + useEffect(() => { + function updateSize() { + if (areaRef.current) { + setSize({ + width: areaRef.current.offsetWidth, + height: areaRef.current.offsetHeight + }) + } + } + updateSize() + addEventListener("resize", updateSize); + return () => { + removeEventListener("resize", updateSize) + }; + }, [areaRef, setSize]) + + return {SizeWrapper, size} +} \ No newline at end of file diff --git a/src/app/page.tsx b/src/app/page.tsx index c4dfe5e..787bac4 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,5 +1,5 @@ 'use client' -import React from 'react'; +import React, { ForwardedRef, ReactNode, RefObject, forwardRef } from 'react'; import Container from 'react-bootstrap/Container'; import AboutBrief from './components/AboutBrief'; import Skills from './components/Skills'; @@ -9,6 +9,7 @@ import Education from './components/Education'; import { Col, Row } from 'react-bootstrap'; import Footer from './components/Footer'; import Photo from './components/Photo'; +import useSize from './hooks/Size'; export default function Home() { return (