moved old homepage, initial version of new homepage

Signed-off-by: Raul Kele <raulkeleblk@gmail.com>
This commit is contained in:
Raul Kele 2022-07-11 18:16:31 +03:00 committed by Ramkumar Chinchani
parent a84ad70fa2
commit 007998e5cf
7 changed files with 329 additions and 20 deletions

View File

@ -10,6 +10,7 @@ import './App.css';
import { BrowserRouter as Router, Routes, Route, Navigate } from "react-router-dom";
import { AuthWrapper } from 'utilities/AuthWrapper.jsx';
import RepoPage from 'pages/RepoPage.jsx';
import ExplorePage from 'pages/ExplorePage.jsx';
const useStyles = makeStyles((theme) => ({
@ -37,6 +38,7 @@ function App() {
<Route element={<AuthWrapper isLoggedIn={isLoggedIn} redirect="/login" />}>
<Route path="/" element={<Navigate to="/home" />} />
<Route path="/home" element={<HomePage keywords={searchKeywords} updateKeywords={setSearchKeywords} data={data} updateData={setData} />} />
<Route path="/explore" element={<ExplorePage keywords={searchKeywords} updateKeywords={setSearchKeywords} data={data} updateData={setData} />} />
<Route path="/image/:name" element={<RepoPage />} />
</Route>
<Route element={<AuthWrapper isLoggedIn={!isLoggedIn} redirect="/"/>}>

View File

@ -1,6 +1,6 @@
// react global
import React from 'react';
import {Link, useLocation} from "react-router-dom";
import {Link, useLocation, useNavigate} from "react-router-dom";
// components
import ExploreHeader from "./ExploreHeader";
@ -66,6 +66,7 @@ const useStyles = makeStyles((theme) => ({
function Header({ updateKeywords }) {
const classes = useStyles();
const path = useLocation().pathname;
const navigate = useNavigate();
const [open, setOpen] = React.useState(false);
const anchorRef = React.useRef(null);
@ -86,11 +87,9 @@ function Header({ updateKeywords }) {
setOpen(false);
};
// onSearch = (event) => {
// this.setState({
// searchValue: event.target.value
// });
// };
const goToExplore = () => {
navigate(`/explore`);
}
return (
<AppBar sx={{position:"sticky", minHeight:"9%"}}>
@ -105,22 +104,17 @@ function Header({ updateKeywords }) {
variant="square"
sx={{ height: 60, width: 64 }}
/>
{
// <Typography className={classes.appName}
// variant="h6"
// noWrap
// component="div"
// color="secondary"
// sx={{ mr: 2, display: { xs: 'none', md: 'flex' } }}>zot
// </Typography>
}
</div>
</Link>
</div>
{path !== '/' &&
<Stack className={classes.search} direction="row" alignItems="center" justifyContent="space-between" spacing={2}>
<InputBase style={{paddingLeft:10,height: 46, color:"rgba(0, 0, 0, 0.6)"}} placeholder="Search for content..." className={classes.input} disabled={path === '/'}/>
<SearchIcon className={classes.searchIcon} />
<InputBase style={{paddingLeft:10,height: 46, color:"rgba(0, 0, 0, 0.6)"}}
placeholder="Search for content..."
className={classes.input}
onKeyDown={() => goToExplore()}
/>
<SearchIcon className={classes.searchIcon}/>
</Stack>}
<div>
<Button

158
src/components/Home.jsx Normal file
View File

@ -0,0 +1,158 @@
import { Grid, Stack, Typography } from '@mui/material';
import { makeStyles } from '@mui/styles';
import { Container } from '@mui/system';
import { api, endpoints } from 'api';
import { host } from '../constants';
import {isEmpty} from 'lodash';
import React, { useEffect, useState } from 'react';
import Loading from './Loading';
import PreviewCard from './PreviewCard';
import RepoCard from './RepoCard';
const useStyles = makeStyles(() => ({
gridWrapper: {
// backgroundColor: "#fff",
},
nodataWrapper: {
backgroundColor: "#fff",
height: '100vh',
},
exploreText: {
color: '#C0C0C0',
display: "flex",
alignItems: "left",
},
resultsRow: {
justifyContent:"space-between",
alignItems:"center",
color:"#00000099"
},
title: {
fontWeight:"700",
textAlign:"center",
color:"#000000DE"
},
subtitle: {
color:"#00000099",
fontWeight:400,
fontSize:"16px",
textAlign:"center",
letterSpacing:"0.15px",
maxWidth:"40%"
}
}));
function Home ({ keywords, data, updateData }) {
const [isLoading, setIsLoading] = useState(true);
const [homeData, setHomeData] = useState([]);
const filterStr = keywords && keywords.toLocaleLowerCase();
const classes = useStyles();
useEffect(() => {
api.get(`${host}${endpoints.imageList}`)
.then(response => {
if (response.data && response.data.data) {
let imageList = response.data.data.ImageListWithLatestTag;
let imagesData = imageList.map((image) => {
return {
name: image.Name,
latestVersion: image.Latest,
tags: image.Labels,
description: image.Description,
licenses: image.Licenses,
size: image.Size,
vendor: image.Vendor,
lastUpdated: image.LastUpdated
};
});
updateData(imagesData);
setIsLoading(false);
}
})
.catch((e) => {
console.error(e);
})
},[])
useEffect(() => {
setIsLoading(false);
}, []);
useEffect(() => {
const filtered = data && data.filter((item) => {
return (
isEmpty(keywords) ||
(item.name && item.name.toLocaleLowerCase().indexOf(filterStr) >= 0 ) ||
(item.appID && item.appID.toLocaleLowerCase().indexOf(filterStr) >= 0) ||
(item.appId && item.appId.toLocaleLowerCase().indexOf(filterStr) >= 0)
)
});
setHomeData(filtered);
}, [keywords, data]);
const renderPreviewCards = () => {
return homeData && homeData.slice(0,4).map((item, index) => {
return (
<Grid item xs={3} key={index}><PreviewCard name={item.name} lastUpdated={item.lastUpdated}/></Grid>
)
});
};
const renderBookmarks = () => {
return homeData && homeData.slice(0,2).map((item,index) => {
return (
<RepoCard name={item.name}
version={item.latestVersion}
description={item.description}
tags={item.tags}
vendor={item.vendor}
size={item.size}
licenses={item.licenses}
key={index}
data={item}
lastUpdated={item.lastUpdated}
shown={true}/>
)
});
}
const renderRecentlyUpdated = () => {
return homeData && homeData.slice(0,2).map((item,index) => {
return (
<RepoCard name={item.name}
version={item.latestVersion}
description={item.description}
tags={item.tags}
vendor={item.vendor}
size={item.size}
licenses={item.licenses}
key={index}
data={item}
lastUpdated={item.lastUpdated}
shown={true}/>
)
});
}
return (
<Stack spacing={5} alignItems="center">
<Grid container item xs={12}>
<Stack direction="column" alignItems="center">
<Typography variant="h3" className={classes.title}>Most popular repositories</Typography>
<Typography variant="body1" className={classes.subtitle} align="center">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Amet, dis pellentesque posuere nulla tortor ac eu arcu nunc. A potenti ridiculus vitae, ut venenatis in ut interdum eros.</Typography>
</Stack>
</Grid>
<Grid container spacing={2}>
{renderPreviewCards()}
</Grid>
<Typography variant="h4" align="left" className={classes.title}>Bookmarks</Typography>
{renderBookmarks()}
<Typography variant="h4" align="left" className={classes.title}>Recently updated repositories</Typography>
{renderRecentlyUpdated()}
</Stack>
);
}
export default Home;

View File

@ -0,0 +1,109 @@
import { Card, CardActionArea, CardContent, CardMedia, Chip, Grid, Typography } from '@mui/material';
import { makeStyles } from '@mui/styles';
import { DateTime } from 'luxon';
import React from 'react';
import { useNavigate } from 'react-router-dom';
import CheckCircleOutlineOutlinedIcon from '@mui/icons-material/CheckCircleOutlineOutlined';
// placeholder images
import repocube1 from '../assets/repocube-1.png';
import repocube2 from '../assets/repocube-2.png';
import repocube3 from '../assets/repocube-3.png';
import repocube4 from '../assets/repocube-4.png';
// temporary utility to get image
const randomIntFromInterval = (min, max) => {
return Math.floor(Math.random() * (max - min + 1) + min)
};
const randomImage = () => {
const imageArray = [repocube1,repocube2,repocube3,repocube4];
return imageArray[randomIntFromInterval(0,3)];
};
const useStyles = makeStyles(() => ({
card: {
marginBottom: 2,
display:"flex",
flexDirection:"row",
alignItems:"center",
background:"#FFFFFF",
boxShadow:"0px 5px 10px rgba(131, 131, 131, 0.08)",
borderRadius:"24px",
flex:"none",
alignSelf:"stretch",
flexGrow:0,
order:0,
width:"100%",
},
avatar: {
height:"23px",
width:"23px"
},
cardBtn: {
height: "100%",
width: "100%"
},
media: {
borderRadius: '50px',
},
content: {
textAlign: "left",
color: "#606060",
},
signedBadge: {
color: '#9ccc65',
height: '22px',
width: '22px',
marginLeft: 10,
}
}));
function RepoCard(props) {
const classes = useStyles();
const navigate = useNavigate();
const {name, lastUpdated} = props;
const goToDetails = (repo) => {
navigate(`/image/${name}`, {state: {lastDate: (lastUpdated? DateTime.fromISO(lastUpdated) : DateTime.now().minus({days:1})).toRelative({unit:'days'})}});
};
const verifiedCheck = () => {
return (<CheckCircleOutlineOutlinedIcon sx={{color:"#388E3C!important"}}/>);
}
return (
<Card variant="outlined" className={classes.card}>
<CardActionArea onClick={() => goToDetails()} className={classes.cardBtn}>
<CardContent className={classes.content}>
<Grid container spacing={1}>
<Grid container item xs={12}>
<CardMedia classes={{
root: classes.media,
img: classes.avatar,
}}
component="img"
image={randomImage()}
alt="icon"
/>
<Typography variant="h5" component="div">
{name}
</Typography>
{verifiedCheck()}
</Grid>
<Grid container item xs={12}>
<Typography variant="body2">Official*PH</Typography>
</Grid>
<Grid container item xs={12}>
</Grid>
<Grid container item xs={12}>
<Typography variant="subtitle2" sx={{color:"#7C4DFF"}}>Discover more</Typography>
</Grid>
</Grid>
</CardContent>
</CardActionArea>
</Card>
);
};
export default RepoCard;

View File

@ -39,7 +39,7 @@ const useStyles = makeStyles(() => ({
alignSelf:"stretch",
flexGrow:0,
order:0,
width:"100%"
width:"100%",
},
avatar: {
height:"23px",
@ -55,7 +55,6 @@ const useStyles = makeStyles(() => ({
content: {
textAlign: "left",
color: "#606060",
padding: "2% 3% 2% 3%"
},
signedBadge: {
color: '#9ccc65',

46
src/pages/ExplorePage.jsx Normal file
View File

@ -0,0 +1,46 @@
// components
import React from 'react';
import Header from '../components/Header.jsx'
import Rightbar from '../components/Rightbar.jsx'
import makeStyles from '@mui/styles/makeStyles';
import {Container, Grid, Stack} from '@mui/material';
const useStyles = makeStyles((theme) => ({
container: {
paddingTop: 30,
paddingBottom: 5,
height: '100%',
minWidth:'60%'
},
gridWrapper: {
// backgroundColor: "#fff",
border: "1px #f2f2f2 dashed",
},
pageWrapper: {
height:"100%"
},
tile: {
width: '100%',
}
}));
function ExplorePage({ data, updateData, keywords, updateKeywords }) {
const classes = useStyles();
return (
<Stack className={classes.pageWrapper} direction="column">
<Header updateKeywords={updateKeywords}></Header>
<Container className={classes.container} >
<Grid container className={classes.gridWrapper}>
<Grid item className={classes.tile}>
<Rightbar keywords={keywords} data={data} updateData={updateData}/>
</Grid>
</Grid>
</Container>
</Stack>
);
}
export default ExplorePage;

View File

@ -5,6 +5,7 @@ import Rightbar from '../components/Rightbar.jsx'
import makeStyles from '@mui/styles/makeStyles';
import {Container, Grid, Stack} from '@mui/material';
import Home from 'components/Home.jsx';
const useStyles = makeStyles((theme) => ({
@ -35,7 +36,7 @@ function HomePage({ data, updateData, keywords, updateKeywords }) {
<Container className={classes.container} >
<Grid container className={classes.gridWrapper}>
<Grid item className={classes.tile}>
<Rightbar keywords={keywords} data={data} updateData={updateData}/>
<Home keywords={keywords} data={data} updateData={updateData}/>
</Grid>
</Grid>
</Container>