moved old homepage, initial version of new homepage
Signed-off-by: Raul Kele <raulkeleblk@gmail.com>
This commit is contained in:
parent
a84ad70fa2
commit
007998e5cf
@ -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="/"/>}>
|
||||
|
@ -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
158
src/components/Home.jsx
Normal 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;
|
109
src/components/PreviewCard.jsx
Normal file
109
src/components/PreviewCard.jsx
Normal 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;
|
@ -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
46
src/pages/ExplorePage.jsx
Normal 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;
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user