diff --git a/public/locales/en/translations.json b/public/locales/en/translations.json index e395d30..4c67fa5 100644 --- a/public/locales/en/translations.json +++ b/public/locales/en/translations.json @@ -64,7 +64,8 @@ "About": { "Navigation": { "System": "System", - "ReleaseNotes": "Release notes" + "ReleaseNotes": "Release notes", + "Timeline": "Timeline" }, "ReleaseNotes": { "Version": "Version", diff --git a/public/locales/ro/translations.json b/public/locales/ro/translations.json index e4cbc3d..b54b91b 100644 --- a/public/locales/ro/translations.json +++ b/public/locales/ro/translations.json @@ -55,7 +55,8 @@ "About": { "Navigation": { "System": "Sistem", - "ReleaseNotes": "Note de lansare" + "ReleaseNotes": "Note de lansare", + "Timeline": "Cronologie" }, "ReleaseNotes": { "Version": "Versiune", diff --git a/src/features/about/AboutContainer.js b/src/features/about/AboutContainer.js index b9a2393..a5b8ed9 100644 --- a/src/features/about/AboutContainer.js +++ b/src/features/about/AboutContainer.js @@ -2,6 +2,7 @@ import React, { useState, useMemo } from "react"; import PageTitle from "../../components/common/PageTitle"; import BubbleChartIcon from "@material-ui/icons/BubbleChart"; import NotesIcon from "@material-ui/icons/Notes"; +import TimelineIcon from "@material-ui/icons/Timeline"; import { useTranslation } from "react-i18next"; import AboutSystemContainer from "./system/AboutSystemContainer"; import ReleaseNotesContainer from "./releaseNotes/ReleaseNotesContainer"; @@ -9,7 +10,8 @@ import NavigationButtons from "../../components/common/NavigationButtons"; const NavigationTabs = { SYSTEM: "About.Navigation.System", - RELEASE_NOTES: "About.Navigation.ReleaseNotes" + RELEASE_NOTES: "About.Navigation.ReleaseNotes", + TIMELINE: "About.Navigation.Timeline" }; const tabs = [ @@ -20,6 +22,10 @@ const tabs = [ { code: NavigationTabs.RELEASE_NOTES, icon: NotesIcon + }, + { + code: NavigationTabs.TIMELINE, + icon: TimelineIcon } ]; @@ -42,6 +48,9 @@ const AboutContainer = () => { /> {tab === NavigationTabs.SYSTEM && } {tab === NavigationTabs.RELEASE_NOTES && } + {tab === NavigationTabs.TIMELINE && ( + + )} ); }; diff --git a/src/features/about/releaseNotes/ReleaseNotesContainer.js b/src/features/about/releaseNotes/ReleaseNotesContainer.js index df69acf..25aff8a 100644 --- a/src/features/about/releaseNotes/ReleaseNotesContainer.js +++ b/src/features/about/releaseNotes/ReleaseNotesContainer.js @@ -1,8 +1,13 @@ import React, { useState, useEffect } from "react"; +import PropTypes from "prop-types"; import useApi from "../../../api"; import ReleaseNotesList from "./ReleaseNotesList"; +import TimelineComponent from "../timeline/TimelineComponent"; -const ReleaseNotesContainer = () => { +const sort = releases => + releases.sort((a, b) => new Date(b.date) - new Date(a.date)); + +const ReleaseNotesContainer = ({ view }) => { const [state, setState] = useState({ data: [], loaded: false }); const api = useApi(); @@ -16,7 +21,20 @@ const ReleaseNotesContainer = () => { }); }, [api, state.loaded]); - return <>{state.loaded && }; + return ( + <> + {state.loaded && + (view === "timeline" ? ( + + ) : ( + + ))} + + ); +}; + +ReleaseNotesContainer.propTypes = { + view: PropTypes.string }; export default ReleaseNotesContainer; diff --git a/src/features/about/releaseNotes/ReleaseNotesList.js b/src/features/about/releaseNotes/ReleaseNotesList.js index d1adf5e..0351a83 100644 --- a/src/features/about/releaseNotes/ReleaseNotesList.js +++ b/src/features/about/releaseNotes/ReleaseNotesList.js @@ -9,7 +9,7 @@ import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; import ReleaseNoteSummary from "./ReleaseNoteSummary"; import ReleaseNote from "./ReleaseNote"; -const ReleaseNotesList = ({ releaseNotes }) => { +const ReleaseNotesList = ({ releases }) => { const [flags, setFlags] = useState({}); const handleToggle = key => (_, expanded) => { @@ -25,22 +25,30 @@ const ReleaseNotesList = ({ releaseNotes }) => { return collapsed; }; + console.log( + "sortedReleases", + JSON.stringify(releases.map(z => ({ version: z.version, date: z.date }))) + ); + return ( <> - {releaseNotes.map(note => { + {releases.map(release => { return ( - + } - id={`panel-${note.version}-header`} + id={`panel-${release.version}-header`} > - + ); @@ -50,7 +58,7 @@ const ReleaseNotesList = ({ releaseNotes }) => { }; ReleaseNotesList.propTypes = { - releaseNotes: PropTypes.array.isRequired + releases: PropTypes.array.isRequired }; export default ReleaseNotesList; diff --git a/src/features/about/timeline/TimelineComponent.js b/src/features/about/timeline/TimelineComponent.js new file mode 100644 index 0000000..7a97331 --- /dev/null +++ b/src/features/about/timeline/TimelineComponent.js @@ -0,0 +1,117 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { makeStyles } from "@material-ui/core/styles"; +import Timeline from "@material-ui/lab/Timeline"; +import TimelineItem from "@material-ui/lab/TimelineItem"; +import TimelineSeparator from "@material-ui/lab/TimelineSeparator"; +import TimelineConnector from "@material-ui/lab/TimelineConnector"; +import TimelineContent from "@material-ui/lab/TimelineContent"; +import TimelineOppositeContent from "@material-ui/lab/TimelineOppositeContent"; +import TimelineDot from "@material-ui/lab/TimelineDot"; +import Paper from "@material-ui/core/Paper"; +import Typography from "@material-ui/core/Typography"; +import { useTranslation } from "react-i18next"; +import { getRandomElement } from "../../../utils"; +import { + Announcement, + AmpStories, + Apps, + BugReport, + DeviceHub, + Equalizer, + FilterTiltShift, + Grain, + Layers, + LocalOffer, + Memory, + NetworkCheck, + OfflineBolt, + Star, + Whatshot, + Widgets +} from "@material-ui/icons"; + +const timelineIcons = [ + Announcement, + AmpStories, + Apps, + BugReport, + DeviceHub, + Equalizer, + FilterTiltShift, + Grain, + Layers, + LocalOffer, + Memory, + NetworkCheck, + OfflineBolt, + Star, + Whatshot, + Widgets +]; + +const timelineDotVariants = [ + { color: "primary", variant: "outlined" }, + { color: "secondary", variant: "outlined" } +]; + +const useStyles = makeStyles(() => ({ + paper: { + padding: "6px 16px" + } +})); + +const TimelineComponent = ({ releases }) => { + const classes = useStyles(); + const { t } = useTranslation(); + + const _releases = releases.map((release, index) => { + const isLast = index === releases.length - 1; + const icon = getRandomElement(timelineIcons); + const dot = getRandomElement(timelineDotVariants); + return { ...release, isLast, icon, dot }; + }); + + return ( + + {_releases.map(release => ( + + + + {t("DATE_FORMAT", { + date: { value: release.date, format: "DD-MM-YYYY HH:mm" } + })} + + + + + + + {!release.isLast && } + + + + + {release.notes[0]} + + {release.notes.slice(1).map((note, index) => ( + + {note} + + ))} + + + + ))} + + ); +}; + +TimelineComponent.propTypes = { + releases: PropTypes.array.isRequired +}; + +export default TimelineComponent; diff --git a/src/themes/default.js b/src/themes/default.js index eb6dad5..d18abd1 100644 --- a/src/themes/default.js +++ b/src/themes/default.js @@ -1,5 +1,5 @@ const primary = "#00695C"; -const secondary = "#FF5C93"; +const secondary = "#F9A825"; const warning = "#ff9800"; const success = "#4caf50"; const info = "#2196f3"; @@ -10,8 +10,8 @@ const defaultTheme = { main: primary }, secondary: { - main: secondary, - contrastText: "#ffcc00" + main: secondary + // contrastText: "#ffcc00" }, warning: { main: warning diff --git a/src/utils/index.js b/src/utils/index.js new file mode 100644 index 0000000..0dbd747 --- /dev/null +++ b/src/utils/index.js @@ -0,0 +1,3 @@ +import { getRandomElement } from "./random"; + +export { getRandomElement }; diff --git a/src/utils/random.js b/src/utils/random.js new file mode 100644 index 0000000..d53d99a --- /dev/null +++ b/src/utils/random.js @@ -0,0 +1,7 @@ +const getRandomElement = array => { + const randomIndex = Math.floor(Math.random() * array.length); + const element = array[randomIndex]; + return element; +}; + +export { getRandomElement };