Skip to content

Commit

Permalink
Redesign home page
Browse files Browse the repository at this point in the history
  • Loading branch information
randombenj committed Oct 16, 2024
1 parent 0d32e26 commit 5ad819c
Show file tree
Hide file tree
Showing 26 changed files with 355 additions and 317 deletions.
29 changes: 0 additions & 29 deletions web/src/components/ClaimButton.tsx

This file was deleted.

29 changes: 0 additions & 29 deletions web/src/components/DeleteButton.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions web/src/components/FavoriteStar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Star, StarOutline } from '@mui/icons-material'
import React, { useState } from 'react'
import { useState } from 'react'
import ProjectRepository from '../repositories/ProjectRepository'

interface Props {
Expand All @@ -24,7 +24,7 @@ export default function FavoriteStar(props: Props): JSX.Element {

return (
<StarType
style={{ color: '#505050', cursor: 'pointer', float: 'right' }}
style={{ color: '#505050', cursor: 'pointer' }}
onClick={toggleFavorite}
/>
)
Expand Down
9 changes: 5 additions & 4 deletions web/src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { Link } from 'react-router-dom'
import styles from './../style/components/Footer.module.css'
import React from 'react'

export default function Footer(): JSX.Element {
return (
<div className={styles.footer}>
<Link to="/help" className={styles['help-link']}>
Help
HELP
</Link>

<div className={styles['version-info']}>
Docat Version{' '}
<code>{import.meta.env.VITE_DOCAT_VERSION ?? 'unknown'}</code>
<Link to="https://github.com/docat-org/docat" target='_blank'>
VERSION{' '}
{import.meta.env.VITE_DOCAT_VERSION ?? 'unknown'}
</Link>
</div>
</div>
)
Expand Down
9 changes: 2 additions & 7 deletions web/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import React, { useState } from 'react'
import { useState } from 'react'
import { Link } from 'react-router-dom'

import SearchBar from './SearchBar'
import { useConfig } from '../data-providers/ConfigDataProvider'

import docatLogo from '../assets/logo.png'
import styles from './../style/components/Header.module.css'

interface Props {
showSearchBar?: boolean
}

export default function Header(props: Props): JSX.Element {
export default function Header(): JSX.Element {
const defaultHeader = (
<>
<img alt="docat logo" src={docatLogo} />
Expand All @@ -30,7 +26,6 @@ export default function Header(props: Props): JSX.Element {
return (
<div className={styles.header}>
<Link to="/">{header}</Link>
{props.showSearchBar !== false && <SearchBar />}
</div>
)
}
1 change: 0 additions & 1 deletion web/src/components/NavigationTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ArrowBackIos } from '@mui/icons-material'
import { Link } from 'react-router-dom'
import React from 'react'

import styles from './../style/components/NavigationTitle.module.css'

Expand Down
3 changes: 1 addition & 2 deletions web/src/components/PageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import styles from './../style/components/PageLayout.module.css'
import Footer from './Footer'
import Header from './Header'
import NavigationTitle from './NavigationTitle'
import React from 'react'

interface Props {
title: string
Expand All @@ -14,7 +13,7 @@ interface Props {
export default function PageLayout(props: Props): JSX.Element {
return (
<>
<Header showSearchBar={props.showSearchBar} />
<Header />
<div className={styles.main}>
<NavigationTitle title={props.title} description={props.description} />
{props.children}
Expand Down
94 changes: 59 additions & 35 deletions web/src/components/Project.tsx
Original file line number Diff line number Diff line change
@@ -1,64 +1,88 @@
import React from 'react'
import { Link } from 'react-router-dom'
import { type Project as ProjectType } from '../models/ProjectsResponse'
import ProjectRepository from '../repositories/ProjectRepository'
import styles from './../style/components/Project.module.css'
import { type Project as ProjectType } from '../models/ProjectsResponse'

import FavoriteStar from './FavoriteStar'
import { Tooltip } from '@mui/material'
import FavoriteStar from './FavoriteStar'

interface Props {
project: ProjectType
onFavoriteChanged: () => void
}

function timeSince(date: Date) {
const seconds = Math.floor((new Date().getUTCMilliseconds() - date.getUTCMilliseconds()) / 1000);
let interval = seconds / 31536000;

if (interval > 1) {
return Math.floor(interval) + " years";
}
interval = seconds / 2592000;
if (interval > 1) {
return Math.floor(interval) + " months";
}
interval = seconds / 86400;
if (interval > 1) {
return Math.floor(interval) + " days";
}
interval = seconds / 3600;
if (interval > 1) {
return Math.floor(interval) + " hours";
}
interval = seconds / 60;
if (interval > 1) {
return Math.floor(interval) + " minutes";
}
return Math.floor(seconds) + " seconds";
}

export default function Project(props: Props): JSX.Element {
const latestVersion = ProjectRepository.getLatestVersion(props.project.versions)

return (
<div className={styles['project-card']}>
<div className={styles['project-card-header']}>
<Tooltip title={props.project.name} placement="top-start" arrow>
<Link to={`${props.project.name}/latest`}>
{props.project.logo ? (
<>

{props.project.logo ?
<>
<Link to={`${props.project.name}/latest`}>
<img
className={styles['project-logo']}
src={ProjectRepository.getProjectLogoURL(props.project.name)}
alt={`${props.project.name} project logo`}
/>
</Link>
</> : <></>
}

<div className={styles['project-header']}>
<Link to={`${props.project.name}/latest`}>
<div className={styles['project-card-title']}>
{props.project.name}{' '}
<span className={styles['secondary-typography']}>
{latestVersion.name}
</span>
</div>
</Link>

<div className={styles['project-card-title-with-logo']}>
{props.project.name}{' '}
<span className={styles['project-card-version']}>
{
ProjectRepository.getLatestVersion(props.project.versions)
.name
}
</span>
</div>
</>
) : (
<div className={styles['project-card-title']}>
{props.project.name}{' '}
<span className={styles['project-card-version']}>
{
ProjectRepository.getLatestVersion(props.project.versions)
.name
}
</span>
</div>
)}
</Link>
<Tooltip title={new Date(latestVersion.timestamp).toISOString().slice(0, -8).replace('T', ' ')} placement="left" arrow>
<div className={styles['secondary-typography']}>
{timeSince(new Date(latestVersion.timestamp))} ago
</div>
</Tooltip>
</div>
<div className={styles['project-header']}>
<div className={styles.subhead}>
{props.project.versions.length === 1
? `${props.project.versions.length} version`
: `${props.project.versions.length} versions`}
</div>

<FavoriteStar
projectName={props.project.name}
onFavoriteChanged={props.onFavoriteChanged}
/>
</div>
<div className={styles.subhead}>
{props.project.versions.length === 1
? `${props.project.versions.length} version`
: `${props.project.versions.length} versions`}
</div>
</div>
)
}
3 changes: 1 addition & 2 deletions web/src/components/ProjectList.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import Project from './Project'
import React from 'react'

import styles from './../style/components/ProjectList.module.css'
import { type Project as ProjectType } from '../models/ProjectsResponse'
import styles from './../style/components/ProjectList.module.css'

interface Props {
projects: ProjectType[]
Expand Down
96 changes: 74 additions & 22 deletions web/src/components/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,74 @@
import _ from 'lodash'
import { TextField } from '@mui/material'
import React, { useCallback } from 'react'
import styles from '../style/components/SearchBar.module.css'
import { useSearch } from '../data-providers/SearchProvider'
import SearchIcon from '@mui/icons-material/Search';
import StarIcon from '@mui/icons-material/Star';
import StarBorderIcon from '@mui/icons-material/StarBorder';
import { Divider, IconButton, InputBase, Paper, Tooltip } from '@mui/material';
import React, { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useSearch } from '../data-providers/SearchProvider';


interface Props {
showFavourites: boolean
onShowFavourites: (all: boolean) => void
}

export default function SearchBar(props: Props): JSX.Element {
const [showFavourites, setShowFavourites] = useState(true);
const [searchParams, setSearchParams] = useSearchParams();

export default function SearchBar(): JSX.Element {
const { query, setQuery } = useSearch()
const [searchQuery, setSearchQuery] = React.useState<string>(query)

const updateSearchQueryInDataProvider = useCallback(
_.debounce((query: string): void => {
setQuery(query)
}, 500),
[]
)

const updateSearch = (q: string) => {
setSearchQuery(q)
setQuery(q)

if (q) {
setSearchParams({q})
} else {
setSearchParams({})
}
}

useEffect(() => {
const q = searchParams.get("q")
if (q) {
updateSearch(q)
}
setShowFavourites(props.showFavourites)
}, [props.showFavourites]);

const onFavourites = (show: boolean): void => {
setSearchParams({})
setSearchQuery("")
setQuery("")

setShowFavourites(show)
props.onShowFavourites(!show)
}

const onSearch = (e: React.ChangeEvent<HTMLInputElement>): void => {
setSearchQuery(e.target.value)
updateSearchQueryInDataProvider.cancel()
updateSearchQueryInDataProvider(e.target.value)
updateSearch(e.target.value)
}

return (
<div className={styles['search-bar']}>
<TextField
label="Search"
type="search"
<Paper
component="form"
sx={{
p: '2px 4px',
display: 'flex',
alignItems: 'center',
width: 600,
marginTop: '24px',
marginLeft: '16px',
marginBottom: '32px'
}}
>
<InputBase
sx={{ ml: 1, flex: 1 }}
placeholder="Search Docs"
inputProps={{ 'aria-label': 'search docs' }}
value={searchQuery}
onChange={onSearch}
onKeyDown={(e): void => {
Expand All @@ -34,8 +77,17 @@ export default function SearchBar(): JSX.Element {
setQuery(searchQuery)
}
}}
variant="standard"
></TextField>
</div>

/>
<IconButton type="button" sx={{ p: '10px' }} aria-label="search">
<SearchIcon />
</IconButton>
<Divider sx={{ height: 28, m: 0.5 }} orientation="vertical" />
<Tooltip title={`Show ${showFavourites ? 'all docs' : 'favourites only'}`} placement="right" arrow>
<IconButton onClick={() => onFavourites(!showFavourites)} sx={{ p: '10px' }} aria-label="directions">
{ showFavourites ? <StarIcon /> : <StarBorderIcon /> }
</IconButton>
</Tooltip>
</Paper>
)
}
Loading

0 comments on commit 5ad819c

Please sign in to comment.