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

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

View File

@@ -1,10 +1,11 @@
import React, { MouseEventHandler } from 'react';
import classNames from 'classnames';
import './badge.scss';
import {Ring} from "../../config";
type BadgeProps = {
onClick?: MouseEventHandler;
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>) {

View File

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

View File

@@ -1,7 +1,9 @@
import React from 'react';
import './flag.scss';
import {FlagType} from "../../model";
interface ItemFlag {
flag: 'default' | 'new' | 'changed';
flag: FlagType;
}
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 Flag from '../Flag/Flag';
import { groupByFirstLetter, Item } from '../../model';
import { translate, ring } from '../../config';
import { translate, Ring } from '../../config';
const containsSearchTerm = (text = '', term = '') => {
// TODO search refinement
@@ -16,7 +16,7 @@ const containsSearchTerm = (text = '', term = '') => {
};
type PageOverviewProps = {
rings: ring[];
rings: Ring[];
search: string;
items: Item[];
leaving: boolean;
@@ -24,7 +24,7 @@ type 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);
useEffect(() => {
@@ -34,7 +34,7 @@ export default function PageOverview({ rings, search: searchProp, items, leaving
setSearch(searchProp);
}, [rings, searchProp]);
const handleRingClick = (ring: ring) => () => {
const handleRingClick = (ring: Ring) => () => {
setRing(ring);
};

View File

@@ -1,12 +1,12 @@
import React from 'react';
import { translate, rings, ring } from '../../config';
import { translate, rings, Ring } from '../../config';
import Badge from '../Badge/Badge';
import Link from '../Link/Link';
import ItemList from '../ItemList/ItemList';
import Flag from '../Flag/Flag';
import { Item, Group } from '../../model';
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];
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) {
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 PageOverview from './PageOverview/PageOverview';
import PageHelp from './PageHelp/PageHelp';
import PageQuadrant from './PageQuadrant/PageQuadrant';
import PageItem from './PageItem/PageItem';
import PageItemMobile from './PageItemMobile/PageItemMobile';
import { quadrants, getItemPageNames, isMobileViewport } from '../config';
import { Item } from '../model';
import {quadrants, getItemPageNames, isMobileViewport} from '../config';
import {Item} from '../model';
export default function Router({ pageName, items, releases }: { pageName: string; items: Item[]; releases: string[] }) {
enum page {
type RouterProps = {
pageName: string
items: Item[]
releases: string[]
}
enum page {
index,
overview,
help,
@@ -17,66 +22,69 @@ export default function Router({ pageName, items, releases }: { pageName: string
itemMobile,
item,
notFound,
}
}
const getPageByName = (items: Item[], pageName: string): page => {
const getPageByName = (items: Item[], pageName: string): page => {
if (pageName === 'index') {
return page.index;
return page.index;
}
if (pageName === 'overview') {
return page.overview;
return page.overview;
}
if (pageName === 'help-and-about-tech-radar') {
return page.help;
return page.help;
}
if (quadrants.includes(pageName)) {
return page.quadrant;
return page.quadrant;
}
if (getItemPageNames(items).includes(pageName)) {
return isMobileViewport() ? page.itemMobile : page.item;
return isMobileViewport() ? page.itemMobile : page.item;
}
return page.notFound;
};
};
const [statePageName, setStatePageName] = useState(pageName);
const [leaving, setLeaving] = useState(false);
const [nextPageName, setNextPageName] = useState<string>('');
export default function Router({pageName, items, releases}: RouterProps) {
const [statePageName, setStatePageName] = useState(pageName);
const [leaving, setLeaving] = useState(false);
const [nextPageName, setNextPageName] = useState<string>('');
useEffect(() => {
const leaving = getPageByName(items, pageName) !== getPageByName(items, statePageName);
if (leaving) {
setLeaving(true);
useEffect(() => {
const nowLeaving = getPageByName(items, pageName) !== getPageByName(items, statePageName);
if (nowLeaving) {
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';
// 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;
// }
// }
import {useState} from "react";
type SetTitleProps = {
title: string
@@ -32,9 +6,15 @@ type SetTitleProps = {
}
export default function SetTitle({title, onSetTitle}: SetTitleProps) {
const [onSetTitleState, setOnSetTitleState] = useState(() => onSetTitle)
if (onSetTitle) {
onSetTitle(title)
}
setOnSetTitleState(onSetTitle)
}
if (onSetTitleState) {
onSetTitleState(title)
}
return null;
}

View File

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

View File

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