diff --git a/app/components/Event/Event.css b/app/components/Event/Event.css index 046d78d2..f2f31cf1 100644 --- a/app/components/Event/Event.css +++ b/app/components/Event/Event.css @@ -6,7 +6,6 @@ display: block; width: 1px; height: 100%; - font-family: monospace; line-height: 1.5em; color: #fff; background-color: var(--color-red); diff --git a/app/components/Event/Event.js b/app/components/Event/Event.js index 81a8cdc9..feeaf934 100644 --- a/app/components/Event/Event.js +++ b/app/components/Event/Event.js @@ -29,7 +29,7 @@ Event.defaultProps = { }; const StyledEvent = styled(Event)` - margin-left: ${props => props.year + 4026}px; + margin-left: ${props => props.year + 4100}px; `; export default StyledEvent; diff --git a/app/components/Header/Header.css b/app/components/Header/Header.css index 0f8a6342..aaf0e3dc 100644 --- a/app/components/Header/Header.css +++ b/app/components/Header/Header.css @@ -26,13 +26,11 @@ } .Header-title { - font-family: monospace; font-size: 1.5rem; text-transform: uppercase; } .Header-link--persons { - font-family: monospace; text-transform: uppercase; } diff --git a/app/components/Sidebar/Sidebar.css b/app/components/Sidebar/Sidebar.css new file mode 100644 index 00000000..2afb0474 --- /dev/null +++ b/app/components/Sidebar/Sidebar.css @@ -0,0 +1,30 @@ +/** @define Sidebar */ + +.Sidebar { + display: flex; + flex-direction: column; + height: 100%; + padding: 1rem; + font-size: 12px; + box-shadow: inset 1rem 0 .75rem -1rem rgba(0, 0, 0, .5); +} + +.Sidebar-title { + margin-bottom: .5em; +} + +.Sidebar-icon { + margin-bottom: 1rem; + font-size: 2rem; + cursor: pointer; +} + +.Sidebar-image { + margin-bottom: 1rem; +} + +.Sidebar-tableCell { + padding: .25em; + white-space: nowrap; + vertical-align: top; +} diff --git a/app/components/Sidebar/Sidebar.js b/app/components/Sidebar/Sidebar.js new file mode 100644 index 00000000..4e7b741a --- /dev/null +++ b/app/components/Sidebar/Sidebar.js @@ -0,0 +1,149 @@ +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import gql from 'graphql-tag'; +import { MdArrowBack } from 'react-icons/md'; +import getAllData from '../../../scripts/cfGraphql-es6'; + +import SidebarContentEvent from './SidebarContentEvent'; +import SidebarContentPerson from './SidebarContentPerson'; +import SidebarContentTime from './SidebarContentTime'; + +import { formatPerson } from '../../../scripts/formatData'; + +import './Sidebar.css'; + +const schemaEvent = id => gql`{ + event(id:"${id}") { + sys { + id + } + name, + year, + }, +}`; + +const schemaPerson = id => gql`{ + person(id:"${id}") { + sys { + id + } + name, + image { + fileName, + url + }, + gender, + startYear, + startVagueness, + endYear, + endVagueness, + stillActive, + father { + sys { + id + } + name + }, + mother { + sys { + id + } + name + }, + childsCollection { + items { + sys { + id + } + name + } + } + }, +}`; + +const schemaTime = id => gql`{ + time(id:"${id}") { + sys { + id + } + name, + startYear, + endYear, + }, +}`; + + +class Sidebar extends PureComponent { + state = { + content: undefined, + } + + componentDidMount() { + this.fetchData(); + } + + componentDidUpdate(prevProps) { + if (this.props.contentElement !== prevProps.contentElement) { + this.fetchData(); + } + } + + async fetchData() { + const { contentElement: { id, type: contentType } } = this.props; + if (id && contentType) { + try { + let data; + if (contentType === 'event') { + data = await getAllData(schemaEvent(id)); + } else if (contentType === 'person') { + data = await getAllData(schemaPerson(id)); + } else if (contentType === 'time') { + data = await getAllData(schemaTime(id)); + } + + this.setState({ + content: data[contentType] && formatPerson(data[contentType]), + }); + } catch (error) { + console.log(error); + } + } else { + this.setState({ + content: undefined, + }); + } + } + + render() { + const { changeSidebarContent, contentElement: { type: contentType } } = this.props; + const { content } = this.state; + + if (!content) return null; + + return ( +
+ changeSidebarContent(undefined)} /> + {contentType === 'event' && } + {contentType === 'person' && } + {contentType === 'time' && } +
+ ); + } +} + +Sidebar.defaultProps = { + contentElement: undefined, +}; + +Sidebar.propTypes = { + contentElement: PropTypes.shape({ + id: PropTypes.string, + type: PropTypes.oneOf([ + 'event', + 'person', + 'time', + ]), + }), +}; + +export default Sidebar; diff --git a/app/components/Sidebar/SidebarContentEvent.js b/app/components/Sidebar/SidebarContentEvent.js new file mode 100644 index 00000000..a7c1f0ae --- /dev/null +++ b/app/components/Sidebar/SidebarContentEvent.js @@ -0,0 +1,33 @@ +import React, { Fragment } from 'react'; +import PropTypes from 'prop-types'; + +import { ourTime } from '../../js/utils'; + +const SidebarContentEvent = ({ name, year }) => ( + +

{name}

+ + + + + + + + +
Jahr: + {ourTime(year)} +
+
+); + +SidebarContentEvent.defaultProps = { + name: undefined, + year: undefined, +}; + +SidebarContentEvent.propTypes = { + name: PropTypes.string, + year: PropTypes.number, +}; + +export default SidebarContentEvent; diff --git a/app/components/Sidebar/SidebarContentPerson.js b/app/components/Sidebar/SidebarContentPerson.js new file mode 100644 index 00000000..e8927daf --- /dev/null +++ b/app/components/Sidebar/SidebarContentPerson.js @@ -0,0 +1,114 @@ +import React, { Fragment } from 'react'; +import PropTypes from 'prop-types'; + +import { ourTime, timeperiod } from '../../js/utils'; + +const SidebarContentPerson = (props) => { + const { + name, + avatar: image, + startYear, + startVagueness, + endYear, + endVagueness, + father, + mother, + childs, + } = props; + + const age = timeperiod(startYear, (endYear || new Date().getFullYear())); + + + return ( + + { image && + + + {`Bild + + } + +

{name}

+ + + + + + + + + + { endYear && + + + + + } + + + + + + + { father && + + + + + } + + { mother && + + + + + } + + { childs.length > 0 && + + + + + } + +
Geboren: + {ourTime(startYear)}{startVagueness && `(${startVagueness})`} +
Gestorben: + {ourTime(endYear)} {endVagueness && `(${endVagueness})`} +
Lebensdauer:{age} Jahre
Vater: + {father} +
Mutter: + {mother} +
Kinder: +
    + { childs.map(child =>
  • {child}
  • )} +
+
+
+ ); +}; + +SidebarContentPerson.defaultProps = { + avatar: undefined, + startYear: undefined, + startVagueness: undefined, + endYear: undefined, + endVagueness: undefined, + father: undefined, + mother: undefined, + childs: [], +}; + +SidebarContentPerson.propTypes = { + name: PropTypes.string.isRequired, + avatar: PropTypes.string, + startYear: PropTypes.number, + startVagueness: PropTypes.string, + endYear: PropTypes.number, + endVagueness: PropTypes.string, + father: PropTypes.string, + mother: PropTypes.string, + childs: PropTypes.array, +}; + +export default SidebarContentPerson; diff --git a/app/components/Sidebar/SidebarContentTime.js b/app/components/Sidebar/SidebarContentTime.js new file mode 100644 index 00000000..042a82d7 --- /dev/null +++ b/app/components/Sidebar/SidebarContentTime.js @@ -0,0 +1,53 @@ +import React, { Fragment } from 'react'; +import PropTypes from 'prop-types'; + +import { ourTime, timeperiod } from '../../js/utils'; + +const SidebarContentTime = ({ + name, startYear, endYear, +}) => { + const duration = timeperiod(startYear, (endYear || new Date().getFullYear())); + + return ( + +

{name}

+ + + + + + + + + + + + + + + + +
Start: + {ourTime(startYear)} +
Ende: + {endYear ? ourTime(endYear) : 'andauernd'} +
Dauer: + {duration} Jahre +
+
+ ); +}; + +SidebarContentTime.defaultProps = { + name: undefined, + startYear: undefined, + endYear: undefined, +}; + +SidebarContentTime.propTypes = { + name: PropTypes.string, + startYear: PropTypes.number, + endYear: PropTypes.number, +}; + +export default SidebarContentTime; diff --git a/app/components/Time/Time.css b/app/components/Time/Time.css index 9a3cbda3..bdd7d171 100644 --- a/app/components/Time/Time.css +++ b/app/components/Time/Time.css @@ -16,45 +16,26 @@ margin-bottom: 1px; padding-right: .5em; padding-left: .5em; - font-family: monospace; color: #000; white-space: nowrap; cursor: pointer; background-color: var(--Time-color); - border-radius: .5em; } .Time:focus { - --Time-color: #24bb9a; outline: none; } -.Time-name { - position: sticky; - left: .5em; - padding-bottom: .25em; -} - -.Time-info { - position: absolute; - top: 100%; - left: .25em; - padding: .4em .5em; - color: var(--text-color); - background-color: #fff; - box-shadow: 2px 2px rgba(0, 0, 0, .125); -} - -.Time.is-active .Time-info { - z-index: 1; +.Time--person:focus { + --Time-color: #24bb9a; } -.Time-image { - width: 150px; +.Time--time:focus { + --Time-color: #ddb938; } -.Time-tableCell { - padding: .25em; - white-space: nowrap; - vertical-align: top; +.Time-name { + position: sticky; + left: .5em; + padding-bottom: .25em; } diff --git a/app/components/Time/Time.js b/app/components/Time/Time.js index f3826351..02a5e663 100644 --- a/app/components/Time/Time.js +++ b/app/components/Time/Time.js @@ -5,7 +5,7 @@ import cs from 'classnames'; import styled from 'styled-components'; import { timeperiod } from '../../js/utils'; -import { calcTimes } from './calcTimes'; +import { calcTimes } from '../../js/calcTimes'; import './Time.css'; @@ -155,7 +155,7 @@ const StyledTime = styled(Time)(({ return ({ width: `${duration}px`, - marginLeft: `${calcedStart + 4026}px`, + marginLeft: `${calcedStart + 4100}px`, background, }); }); diff --git a/app/components/Time/TimeContentPerson.js b/app/components/Time/TimeContentPerson.js deleted file mode 100644 index c587dda6..00000000 --- a/app/components/Time/TimeContentPerson.js +++ /dev/null @@ -1,106 +0,0 @@ -import React, { Fragment } from 'react'; -import PropTypes from 'prop-types'; - -import { ourTime } from '../../js/utils'; - -const TimeContentPerson = (props) => { - const { - name, - avatar: image, - startYear: birth, - endYear: death, - duration: age, - father, - mother, - childs, - } = props; - - return ( - - { image && - - - {`Bild - - } - - - - - - - - - - { death && - - - - - } - - - - - - - { father && - - - - - } - - { mother && - - - - - } - - { childs.length > 0 && - - - - - } - -
Geboren: - {ourTime(birth)} -
Gestorben: - {ourTime(death)} -
Lebensdauer:{age} Jahre
Vater: - {father} -
Mutter: - {mother} -
Kinder: -
    - { childs.map(child =>
  • {child}
  • )} -
-
-
- ); -}; - -TimeContentPerson.defaultProps = { - avatar: undefined, - startYear: undefined, - endYear: undefined, - duration: undefined, - father: undefined, - mother: undefined, - childs: [], -}; - -TimeContentPerson.propTypes = { - name: PropTypes.string.isRequired, - avatar: PropTypes.string, - startYear: PropTypes.number, - endYear: PropTypes.number, - duration: PropTypes.number, - father: PropTypes.string, - mother: PropTypes.string, - childs: PropTypes.array, -}; - -export default TimeContentPerson; diff --git a/app/components/Time/TimeContentTime.js b/app/components/Time/TimeContentTime.js deleted file mode 100644 index 8a02f911..00000000 --- a/app/components/Time/TimeContentTime.js +++ /dev/null @@ -1,32 +0,0 @@ -import React, { Fragment } from 'react'; - -import { ourTime } from '../../js/utils'; - -const TimeContentTime = ({ startYear, endYear, duration }) => ( - - - - - - - - - - - - - - - - -
Start: - {ourTime(startYear)} -
Ende: - {ourTime(endYear)} -
Dauer: - {duration} Jahre -
-
-); - -export default TimeContentTime; diff --git a/app/components/Timeline/Timeline.css b/app/components/Timeline/Timeline.css index 71c6c8a4..92832dfd 100644 --- a/app/components/Timeline/Timeline.css +++ b/app/components/Timeline/Timeline.css @@ -1,24 +1,16 @@ /** @define Timeline */ :root { - --Time-yearsBeforeZero: 4026px; + --Time-yearsBeforeZero: 4100px; --Time-yearsAfterZero: 2200px; } .Timeline { position: relative; width: calc(var(--Time-yearsBeforeZero) + var(--Time-yearsAfterZero)); - height: 100%; font-size: 10px; color: var(--color-brown); - background-image: - linear-gradient( - to bottom, - var(--body-background-shadow) 0%, - var(--body-background-color) 50%, - var(--body-background-shadow) 100% - ); - background-size: auto 100%; + background-color: #f0f0f0; } .Timeline-scale { @@ -57,7 +49,7 @@ top: .25em; display: flex; padding-right: 17px; - padding-left: 26px; + padding-left: 5px; } .Timeline-negativeNumbers { @@ -71,7 +63,7 @@ .Timeline-scaleNumber { width: 100px; - padding-left: .25rem; + padding-left: 0; font-family: monospace; } diff --git a/app/components/Timeline/Timeline.js b/app/components/Timeline/Timeline.js index e1b8877b..dba3de7a 100644 --- a/app/components/Timeline/Timeline.js +++ b/app/components/Timeline/Timeline.js @@ -2,8 +2,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import Time from '../Time/Time'; -import TimeContentPerson from '../Time/TimeContentPerson'; -import TimeContentTime from '../Time/TimeContentTime'; import Event from '../Event/Event'; import './Timeline.css'; @@ -98,11 +96,20 @@ class Timeline extends Component { } render() { - const { persons, times, events } = this.props; - const { activePersons, activeTimes, activeEvents } = this.state; + const { + persons, + times, + events, + changeSidebarContent, + } = this.props; + const { + activePersons, + activeTimes, + activeEvents, + } = this.state; const scaleNumberNegativ = []; - for (let i = 0; i <= 40; i += 1) { + for (let i = 0; i <= 41; i += 1) { scaleNumberNegativ.push(
{i * -100 }
); } @@ -123,47 +130,32 @@ class Timeline extends Component {
- { events && events.map((eventData, key) => { - const { id, ...event } = eventData; - return ( - this.handleElementClick('event', id)} /> - ); - })} - - { persons && persons.map((personData, key) => { - const { id, ...person } = personData; - return ( - - ); - })} - - { times && times.map((timeData, key) => { - const { id, ...time } = timeData; - return ( - - ); - })} + { events && events.map(({ id, ...event }, key) => ( + changeSidebarContent(id, 'event')} /> + ))} + + { persons && persons.map(({ id, ...person }) => ( +
); diff --git a/app/css/shame.css b/app/css/shame.css index 9e39a6bf..2a78bd13 100644 --- a/app/css/shame.css +++ b/app/css/shame.css @@ -1,3 +1,18 @@ /* * Shame.css */ + +.Page { + display: flex; + height: 100vh; +} + +.Page-wrapSidebar { + flex-shrink: 0; + flex-basis: 16rem; +} + +.Page-wrapTimeline { + flex-grow: 1; + overflow: auto; +} diff --git a/app/css/theme.css b/app/css/theme.css index d1069563..77ee055f 100644 --- a/app/css/theme.css +++ b/app/css/theme.css @@ -4,12 +4,6 @@ * This defines the theme in fundamental terms. */ -/* - * Breakpoints - */ -@custom-media --viewport-sm (min-width: 480px); -@custom-media --viewport-md (min-width: 768px); -@custom-media --viewport-lg (min-width: 992px); /* * Content Widths @@ -76,9 +70,17 @@ --font-size: 16px; - /* --font-family: WtClearText, Georgia, serif; */ + --font-family: + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Helvetica, + Arial, + sans-serif, + 'Apple Color Emoji', + 'Segoe UI Emoji', + 'Segoe UI Symbol'; - --font-family: monospace; --font-weight: 500; --line-height: 1.4; diff --git a/app/components/Time/calcTimes.js b/app/js/calcTimes.js similarity index 100% rename from app/components/Time/calcTimes.js rename to app/js/calcTimes.js