cleanup and fix fading

This commit is contained in:
Bastian Ike
2020-07-17 09:28:02 +02:00
committed by Bastian
parent ed2a4241b8
commit 40e7dd709a
13 changed files with 538 additions and 1295 deletions

View File

@@ -51,6 +51,7 @@
"live-server": "1.2.1", "live-server": "1.2.1",
"marked": "0.3.18", "marked": "0.3.18",
"moment": "2.22.1", "moment": "2.22.1",
"node-sass": "^4.14.1",
"postcss-cli": "^7.1.1", "postcss-cli": "^7.1.1",
"postcss-css-variables": "0.8.0", "postcss-css-variables": "0.8.0",
"postcss-custom-media": "^6.0.0", "postcss-custom-media": "^6.0.0",

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +1,18 @@
import React, { useState } from 'react'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import Header from './Header/Header'; import Header from './Header/Header';
import Footer from './Footer/Footer'; import Footer from './Footer/Footer';
import Router from './Router'; import Router from './Router';
import { BrowserRouter, Switch, Route, Redirect, useParams } from 'react-router-dom'; import { BrowserRouter, Switch, Route, Redirect, useParams } from 'react-router-dom';
import radardata from '../rd.json'; import radardata from '../rd.json';
import { Item } from '../model'; import { Item } from '../model';
const A = () => { const RouterWithPageParam = () => {
const { page } = useParams(); const { page } = useParams();
return <Router pageName={page} items={radardata.items as Item[]} releases={radardata.releases as string[]}></Router>; return <Router pageName={page} items={radardata.items as Item[]} releases={radardata.releases as string[]}/>;
}; };
export default function App() { export default function App() {
const [isFaded] = useState(false);
return ( return (
<BrowserRouter> <BrowserRouter>
<div> <div>
@@ -23,10 +20,10 @@ export default function App() {
<div className='page__header'> <div className='page__header'>
<Header pageName='a' /> <Header pageName='a' />
</div> </div>
<div className={classNames('page__content', { 'is-faded': isFaded })}> <div className={classNames('page__content')}>
<Switch> <Switch>
<Route path={'/techradar/:page(.+).html'}> <Route path={'/techradar/:page(.+).html'}>
<A /> <RouterWithPageParam />
</Route> </Route>
<Route path={'/'}> <Route path={'/'}>
<Redirect to={'/techradar/index.html'} /> <Redirect to={'/techradar/index.html'} />

View File

@@ -1,10 +1,11 @@
import React, { MouseEventHandler } from 'react'; import React, { MouseEventHandler } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import './badge.scss'; import './badge.scss';
import {Ring} from "../../config";
type BadgeProps = { type BadgeProps = {
onClick?: MouseEventHandler; onClick?: MouseEventHandler;
big?: boolean; big?: boolean;
type: 'big' | 'all' | 'adopt' | 'trial' | 'assess' | 'hold' | 'empty'; type: 'big' | 'all' | 'empty' | Ring;
}; };
export default function Badge({ onClick, big, type, children }: React.PropsWithChildren<BadgeProps>) { export default function Badge({ onClick, big, type, children }: React.PropsWithChildren<BadgeProps>) {

View File

@@ -1,6 +1,7 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import './fadeable.scss'; import './fadeable.scss';
type FadeableProps = { type FadeableProps = {
leaving: boolean; leaving: boolean;
onLeave: () => void; onLeave: () => void;
@@ -10,8 +11,12 @@ export default function Fadeable({ leaving, onLeave, children }: React.PropsWith
const [faded, setFaded] = useState(leaving); const [faded, setFaded] = useState(leaving);
useEffect(() => { useEffect(() => {
setFaded(leaving); if (!faded && leaving) {
}, [leaving]); setFaded(true);
} else if (faded && !leaving) {
setFaded(false);
}
}, [faded, leaving]);
const handleTransitionEnd = () => { const handleTransitionEnd = () => {
if (faded) { if (faded) {

View File

@@ -1,7 +1,9 @@
import React from 'react'; import React from 'react';
import './flag.scss'; import './flag.scss';
import {FlagType} from "../../model";
interface ItemFlag { interface ItemFlag {
flag: 'default' | 'new' | 'changed'; flag: FlagType;
} }
export default function Flag({ item, short = false }: { item: ItemFlag; short?: boolean }) { export default function Flag({ item, short = false }: { item: ItemFlag; short?: boolean }) {

View File

@@ -8,7 +8,7 @@ import Fadeable from '../Fadeable/Fadeable';
import SetTitle from '../SetTitle'; import SetTitle from '../SetTitle';
import Flag from '../Flag/Flag'; import Flag from '../Flag/Flag';
import { groupByFirstLetter, Item } from '../../model'; import { groupByFirstLetter, Item } from '../../model';
import { translate, ring } from '../../config'; import { translate, Ring } from '../../config';
const containsSearchTerm = (text = '', term = '') => { const containsSearchTerm = (text = '', term = '') => {
// TODO search refinement // TODO search refinement
@@ -16,7 +16,7 @@ const containsSearchTerm = (text = '', term = '') => {
}; };
type PageOverviewProps = { type PageOverviewProps = {
rings: ring[]; rings: Ring[];
search: string; search: string;
items: Item[]; items: Item[];
leaving: boolean; leaving: boolean;
@@ -24,7 +24,7 @@ type PageOverviewProps = {
}; };
export default function PageOverview({ rings, search: searchProp, items, leaving, onLeave }: PageOverviewProps) { export default function PageOverview({ rings, search: searchProp, items, leaving, onLeave }: PageOverviewProps) {
const [ring, setRing] = useState<ring | 'all'>('all'); const [ring, setRing] = useState<Ring | 'all'>('all');
const [search, setSearch] = useState(searchProp); const [search, setSearch] = useState(searchProp);
useEffect(() => { useEffect(() => {
@@ -34,7 +34,7 @@ export default function PageOverview({ rings, search: searchProp, items, leaving
setSearch(searchProp); setSearch(searchProp);
}, [rings, searchProp]); }, [rings, searchProp]);
const handleRingClick = (ring: ring) => () => { const handleRingClick = (ring: Ring) => () => {
setRing(ring); setRing(ring);
}; };

View File

@@ -1,12 +1,12 @@
import React from 'react'; import React from 'react';
import { translate, rings, ring } from '../../config'; import { translate, rings, Ring } from '../../config';
import Badge from '../Badge/Badge'; import Badge from '../Badge/Badge';
import Link from '../Link/Link'; import Link from '../Link/Link';
import ItemList from '../ItemList/ItemList'; import ItemList from '../ItemList/ItemList';
import Flag from '../Flag/Flag'; import Flag from '../Flag/Flag';
import { Item, Group } from '../../model'; import { Item, Group } from '../../model';
import './quadrant-section.scss'; import './quadrant-section.scss';
const renderList = (ringName: ring, quadrantName: string, groups: Group, big: boolean) => { const renderList = (ringName: Ring, quadrantName: string, groups: Group, big: boolean) => {
const itemsInRing = groups[quadrantName][ringName]; const itemsInRing = groups[quadrantName][ringName];
if (big) { if (big) {
@@ -36,7 +36,7 @@ const renderList = (ringName: ring, quadrantName: string, groups: Group, big: bo
); );
}; };
const renderRing = (ringName: ring, quadrantName: string, groups: Group, big: boolean) => { const renderRing = (ringName: Ring, quadrantName: string, groups: Group, big: boolean) => {
if (!groups[quadrantName] || !groups[quadrantName][ringName] || groups[quadrantName][ringName].length === 0) { if (!groups[quadrantName] || !groups[quadrantName][ringName] || groups[quadrantName][ringName].length === 0) {
return null; return null;
} }

View File

@@ -1,15 +1,20 @@
import React, { useState, useEffect } from 'react'; import React, {useState, useEffect} from 'react';
import PageIndex from './PageIndex/PageIndex'; import PageIndex from './PageIndex/PageIndex';
import PageOverview from './PageOverview/PageOverview'; import PageOverview from './PageOverview/PageOverview';
import PageHelp from './PageHelp/PageHelp'; import PageHelp from './PageHelp/PageHelp';
import PageQuadrant from './PageQuadrant/PageQuadrant'; import PageQuadrant from './PageQuadrant/PageQuadrant';
import PageItem from './PageItem/PageItem'; import PageItem from './PageItem/PageItem';
import PageItemMobile from './PageItemMobile/PageItemMobile'; import PageItemMobile from './PageItemMobile/PageItemMobile';
import { quadrants, getItemPageNames, isMobileViewport } from '../config'; import {quadrants, getItemPageNames, isMobileViewport} from '../config';
import { Item } from '../model'; import {Item} from '../model';
export default function Router({ pageName, items, releases }: { pageName: string; items: Item[]; releases: string[] }) { type RouterProps = {
enum page { pageName: string
items: Item[]
releases: string[]
}
enum page {
index, index,
overview, overview,
help, help,
@@ -17,66 +22,69 @@ export default function Router({ pageName, items, releases }: { pageName: string
itemMobile, itemMobile,
item, item,
notFound, notFound,
} }
const getPageByName = (items: Item[], pageName: string): page => { const getPageByName = (items: Item[], pageName: string): page => {
if (pageName === 'index') { if (pageName === 'index') {
return page.index; return page.index;
} }
if (pageName === 'overview') { if (pageName === 'overview') {
return page.overview; return page.overview;
} }
if (pageName === 'help-and-about-tech-radar') { if (pageName === 'help-and-about-tech-radar') {
return page.help; return page.help;
} }
if (quadrants.includes(pageName)) { if (quadrants.includes(pageName)) {
return page.quadrant; return page.quadrant;
} }
if (getItemPageNames(items).includes(pageName)) { if (getItemPageNames(items).includes(pageName)) {
return isMobileViewport() ? page.itemMobile : page.item; return isMobileViewport() ? page.itemMobile : page.item;
} }
return page.notFound; return page.notFound;
}; };
const [statePageName, setStatePageName] = useState(pageName); export default function Router({pageName, items, releases}: RouterProps) {
const [leaving, setLeaving] = useState(false); const [statePageName, setStatePageName] = useState(pageName);
const [nextPageName, setNextPageName] = useState<string>(''); const [leaving, setLeaving] = useState(false);
const [nextPageName, setNextPageName] = useState<string>('');
useEffect(() => { useEffect(() => {
const leaving = getPageByName(items, pageName) !== getPageByName(items, statePageName); const nowLeaving = getPageByName(items, pageName) !== getPageByName(items, statePageName);
if (leaving) { if (nowLeaving) {
setLeaving(true); setLeaving(true);
setNextPageName(pageName);
} else {
setStatePageName(pageName);
}
}, [pageName, items, statePageName]);
const handlePageLeave = () => {
setLeaving(true);
setStatePageName(nextPageName);
setNextPageName('');
window.setTimeout(() => {
window.requestAnimationFrame(() => {
setLeaving(false);
});
}, 0);
};
switch (getPageByName(items, statePageName)) {
case page.index:
return <PageIndex leaving={leaving} items={items} onLeave={handlePageLeave} releases={releases}/>;
case page.overview:
return <PageOverview items={items} rings={[]} search={''} leaving={leaving} onLeave={handlePageLeave}/>;
case page.help:
return <PageHelp leaving={leaving} onLeave={handlePageLeave}/>;
case page.quadrant:
return <PageQuadrant leaving={leaving} onLeave={handlePageLeave} items={items} pageName={pageName}/>;
case page.itemMobile:
return <PageItemMobile items={items} pageName={pageName} leaving={leaving} onLeave={handlePageLeave}/>;
case page.item:
return <PageItem items={items} pageName={pageName} leaving={leaving} onLeave={handlePageLeave}/>;
default:
return <div/>;
} }
setNextPageName(pageName);
}, [pageName, items, statePageName]);
const handlePageLeave = () => {
setLeaving(true);
setStatePageName(nextPageName);
setNextPageName('');
window.setTimeout(() => {
window.requestAnimationFrame(() => {
setLeaving(false);
});
}, 0);
};
switch (getPageByName(items, pageName)) {
case page.index:
return <PageIndex leaving={leaving} items={items} onLeave={handlePageLeave} releases={releases} />;
case page.overview:
return <PageOverview items={items} rings={[]} search={''} leaving={leaving} onLeave={handlePageLeave} />;
case page.help:
return <PageHelp leaving={leaving} onLeave={handlePageLeave} />;
case page.quadrant:
return <PageQuadrant leaving={leaving} onLeave={handlePageLeave} items={items} pageName={pageName} />;
case page.itemMobile:
return <PageItemMobile items={items} pageName={pageName} leaving={leaving} onLeave={handlePageLeave} />;
case page.item:
return <PageItem items={items} pageName={pageName} leaving={leaving} onLeave={handlePageLeave} />;
default:
return <div />;
}
} }

View File

@@ -1,30 +1,4 @@
// import React from 'react'; import {useState} from "react";
// todo fix this mess
// const _callSetTitle = (props) => {
// if (typeof props.onSetTitle === 'function' && props.title) {
// props.onSetTitle(props.title);
// }
// };
// class _SetTitle extends React.Component {
// constructor(props) {
// super(props);
// _callSetTitle(props);
// }
// componentWillReceiveProps(nextProps) {
// if (nextProps.title !== this.props.title) {
// _callSetTitle(nextProps);
// }
// }
// render() {
// return null;
// }
// }
type SetTitleProps = { type SetTitleProps = {
title: string title: string
@@ -32,9 +6,15 @@ type SetTitleProps = {
} }
export default function SetTitle({title, onSetTitle}: SetTitleProps) { export default function SetTitle({title, onSetTitle}: SetTitleProps) {
const [onSetTitleState, setOnSetTitleState] = useState(() => onSetTitle)
if (onSetTitle) { if (onSetTitle) {
onSetTitle(title) setOnSetTitleState(onSetTitle)
} }
if (onSetTitleState) {
onSetTitleState(title)
}
return null; return null;
} }

View File

@@ -1,4 +1,3 @@
// import moment from 'moment';
import { Item, Radar } from './model'; import { Item, Radar } from './model';
export const radarName = 'AOE Technology Radar'; export const radarName = 'AOE Technology Radar';
@@ -11,12 +10,22 @@ export const quadrants = [
'tools', 'tools',
]; ];
export const rings = [
'adopt',
'trial',
'assess',
'hold'
] as const;
export type Ring = typeof rings[number]
// todo: fix
export function assetUrl(file: string) { export function assetUrl(file: string) {
return '/' + file; return '/' + file;
// return `/techradar/assets/${file}` // return `/techradar/assets/${file}`
} }
export const getPageNames = (radar: Radar) => { const getPageNames = (radar: Radar) => {
return [ return [
'index', 'index',
'overview', 'overview',
@@ -29,15 +38,6 @@ export const getPageNames = (radar: Radar) => {
export const getItemPageNames = (items: Item[]) => items.map(item => `${item.quadrant}/${item.name}`); export const getItemPageNames = (items: Item[]) => items.map(item => `${item.quadrant}/${item.name}`);
export type ring = "adopt" | "trial" | "assess" | "hold"
export const rings: ring[] = [
'adopt',
'trial',
'assess',
'hold'
];
const messages:{[k: string]: string} = { const messages:{[k: string]: string} = {
'languages-and-frameworks': 'Languages & Frameworks', 'languages-and-frameworks': 'Languages & Frameworks',
'methods-and-patterns': 'Methods & Patterns', 'methods-and-patterns': 'Methods & Patterns',

View File

@@ -1,18 +1,20 @@
import { ring } from "./config" import { Ring } from "./config"
export type ItemAttributes = { export type ItemAttributes = {
name: string name: string
ring: ring ring: Ring
quadrant: string quadrant: string
title: string title: string
featured: boolean featured: boolean
} }
export type FlagType = 'new' | 'changed' | 'default'
export type Item = ItemAttributes & { export type Item = ItemAttributes & {
featured: boolean featured: boolean
body: string body: string
info: string info: string
flag: 'new' | 'changed' | 'default' flag: FlagType
revisions: Revision[] revisions: Revision[]
} }

608
yarn.lock

File diff suppressed because it is too large Load Diff