explose page and repo card work
Signed-off-by: Raul Kele <raulkeleblk@gmail.com>
This commit is contained in:
parent
197310999b
commit
faf481c0c5
75
package-lock.json
generated
75
package-lock.json
generated
@ -10,8 +10,6 @@
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.9.3",
|
||||
"@emotion/styled": "^11.9.3",
|
||||
"@material-ui/core": "^4.12.3",
|
||||
"@material-ui/icons": "^4.11.2",
|
||||
"@mui-treasury/styles": "^1.13.1",
|
||||
"@mui/icons-material": "^5.2.5",
|
||||
"@mui/material": "^5.8.6",
|
||||
@ -20,6 +18,7 @@
|
||||
"@testing-library/react": "^12.1.2",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"axios": "^0.24.0",
|
||||
"luxon": "^2.4.0",
|
||||
"npm": "^8.11.0",
|
||||
"nth-check": "^2.0.1",
|
||||
"react": "^17.0.2",
|
||||
@ -2834,6 +2833,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.12.3.tgz",
|
||||
"integrity": "sha512-sdpgI/PL56QVsEJldwEe4FFaFTLUqN+rd7sSZiRCdx2E/C7z5yK0y/khAWVBH24tXwto7I1hCzNWfJGZIYJKnw==",
|
||||
"deprecated": "You can now upgrade to @mui/material. See the guide: https://mui.com/guides/migration-v4/",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@material-ui/styles": "^4.11.4",
|
||||
@ -2866,34 +2866,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@material-ui/icons": {
|
||||
"version": "4.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.2.tgz",
|
||||
"integrity": "sha512-fQNsKX2TxBmqIGJCSi3tGTO/gZ+eJgWmMJkgDiOfyNaunNaxcklJQFaFogYcFl0qFuaEz1qaXYXboa/bUXVSOQ==",
|
||||
"deprecated": "You can now upgrade to @mui/icons. See the guide: https://mui.com/guides/migration-v4/",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.4.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@material-ui/core": "^4.0.0",
|
||||
"@types/react": "^16.8.6 || ^17.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@material-ui/styles": {
|
||||
"version": "4.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.4.tgz",
|
||||
"integrity": "sha512-KNTIZcnj/zprG5LW0Sao7zw+yG3O35pviHzejMdcSGCdWbiO8qzRgOYL8JAxAsWBKOKYwVZxXtHWaB5T2Kvxew==",
|
||||
"deprecated": "You can now upgrade to @mui/styles. See the guide: https://mui.com/guides/migration-v4/",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@emotion/hash": "^0.8.0",
|
||||
@ -2933,13 +2911,15 @@
|
||||
"node_modules/@material-ui/styles/node_modules/csstype": {
|
||||
"version": "2.6.20",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
|
||||
"integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA=="
|
||||
"integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@material-ui/system": {
|
||||
"version": "4.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.12.1.tgz",
|
||||
"integrity": "sha512-lUdzs4q9kEXZGhbN7BptyiS1rLNHe6kG9o8Y307HCvF4sQxbCgpL2qi+gUk+yI8a2DNk48gISEQxoxpgph0xIw==",
|
||||
"deprecated": "You can now upgrade to @mui/system. See the guide: https://mui.com/guides/migration-v4/",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@material-ui/utils": "^4.11.2",
|
||||
@ -2967,12 +2947,14 @@
|
||||
"node_modules/@material-ui/system/node_modules/csstype": {
|
||||
"version": "2.6.20",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
|
||||
"integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA=="
|
||||
"integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@material-ui/types": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
|
||||
"integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"@types/react": "*"
|
||||
},
|
||||
@ -2986,6 +2968,7 @@
|
||||
"version": "4.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz",
|
||||
"integrity": "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"prop-types": "^15.7.2",
|
||||
@ -11646,6 +11629,14 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/luxon": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.4.0.tgz",
|
||||
"integrity": "sha512-w+NAwWOUL5hO0SgwOHsMBAmZ15SoknmQXhSO0hIbJCAmPKSsGeK8MlmhYh2w6Iib38IxN2M+/ooXWLbeis7GuA==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/lz-string": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
|
||||
@ -14795,7 +14786,8 @@
|
||||
"node_modules/popper.js": {
|
||||
"version": "1.16.1-lts",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
|
||||
"integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
|
||||
"integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/portfinder": {
|
||||
"version": "1.0.28",
|
||||
@ -21168,6 +21160,7 @@
|
||||
"version": "4.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.12.3.tgz",
|
||||
"integrity": "sha512-sdpgI/PL56QVsEJldwEe4FFaFTLUqN+rd7sSZiRCdx2E/C7z5yK0y/khAWVBH24tXwto7I1hCzNWfJGZIYJKnw==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@material-ui/styles": "^4.11.4",
|
||||
@ -21183,18 +21176,11 @@
|
||||
"react-transition-group": "^4.4.0"
|
||||
}
|
||||
},
|
||||
"@material-ui/icons": {
|
||||
"version": "4.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.2.tgz",
|
||||
"integrity": "sha512-fQNsKX2TxBmqIGJCSi3tGTO/gZ+eJgWmMJkgDiOfyNaunNaxcklJQFaFogYcFl0qFuaEz1qaXYXboa/bUXVSOQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4"
|
||||
}
|
||||
},
|
||||
"@material-ui/styles": {
|
||||
"version": "4.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.4.tgz",
|
||||
"integrity": "sha512-KNTIZcnj/zprG5LW0Sao7zw+yG3O35pviHzejMdcSGCdWbiO8qzRgOYL8JAxAsWBKOKYwVZxXtHWaB5T2Kvxew==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@emotion/hash": "^0.8.0",
|
||||
@ -21217,7 +21203,8 @@
|
||||
"csstype": {
|
||||
"version": "2.6.20",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
|
||||
"integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA=="
|
||||
"integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==",
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -21225,6 +21212,7 @@
|
||||
"version": "4.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.12.1.tgz",
|
||||
"integrity": "sha512-lUdzs4q9kEXZGhbN7BptyiS1rLNHe6kG9o8Y307HCvF4sQxbCgpL2qi+gUk+yI8a2DNk48gISEQxoxpgph0xIw==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@material-ui/utils": "^4.11.2",
|
||||
@ -21235,7 +21223,8 @@
|
||||
"csstype": {
|
||||
"version": "2.6.20",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
|
||||
"integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA=="
|
||||
"integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==",
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -21243,12 +21232,14 @@
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
|
||||
"integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==",
|
||||
"peer": true,
|
||||
"requires": {}
|
||||
},
|
||||
"@material-ui/utils": {
|
||||
"version": "4.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz",
|
||||
"integrity": "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"prop-types": "^15.7.2",
|
||||
@ -27521,6 +27512,11 @@
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"luxon": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.4.0.tgz",
|
||||
"integrity": "sha512-w+NAwWOUL5hO0SgwOHsMBAmZ15SoknmQXhSO0hIbJCAmPKSsGeK8MlmhYh2w6Iib38IxN2M+/ooXWLbeis7GuA=="
|
||||
},
|
||||
"lz-string": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
|
||||
@ -29672,7 +29668,8 @@
|
||||
"popper.js": {
|
||||
"version": "1.16.1-lts",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
|
||||
"integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
|
||||
"integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==",
|
||||
"peer": true
|
||||
},
|
||||
"portfinder": {
|
||||
"version": "1.0.28",
|
||||
|
@ -13,6 +13,7 @@
|
||||
"@testing-library/react": "^12.1.2",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"axios": "^0.24.0",
|
||||
"luxon": "^2.4.0",
|
||||
"npm": "^8.11.0",
|
||||
"nth-check": "^2.0.1",
|
||||
"react": "^17.0.2",
|
||||
|
@ -1,5 +1,6 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
@ -44,9 +45,3 @@
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.card-link {
|
||||
display: block;
|
||||
height: 200px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
BIN
src/assets/repocube-1.png
Normal file
BIN
src/assets/repocube-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 612 B |
BIN
src/assets/repocube-2.png
Normal file
BIN
src/assets/repocube-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 605 B |
BIN
src/assets/repocube-3.png
Normal file
BIN
src/assets/repocube-3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 630 B |
BIN
src/assets/repocube-4.png
Normal file
BIN
src/assets/repocube-4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 600 B |
@ -2,23 +2,24 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
// components
|
||||
import ImageTile from './ImageTile.jsx';
|
||||
import RepoCard from './RepoCard.jsx';
|
||||
import Loading from "./Loading";
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Alert from '@mui/material/Alert';
|
||||
import { Container, Grid } from '@mui/material';
|
||||
import { Container, FormControl, Grid, InputLabel, Select, Stack } from '@mui/material';
|
||||
|
||||
import makeStyles from '@mui/styles/makeStyles';
|
||||
|
||||
// utility
|
||||
import api from '../api.js';
|
||||
import {URL} from '../constants';
|
||||
import {host} from '../constants';
|
||||
import {isEmpty} from 'lodash';
|
||||
//
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
gridWrapper: {
|
||||
backgroundColor: "#fff",
|
||||
// backgroundColor: "#fff",
|
||||
},
|
||||
nodataWrapper: {
|
||||
backgroundColor: "#fff",
|
||||
@ -28,6 +29,10 @@ const useStyles = makeStyles(() => ({
|
||||
color: '#C0C0C0',
|
||||
display: "flex",
|
||||
alignItems: "left",
|
||||
},
|
||||
resultsRow: {
|
||||
justifyContent:"space-between",
|
||||
alignItems:"center"
|
||||
}
|
||||
}));
|
||||
|
||||
@ -37,7 +42,7 @@ function Explore ({ keywords, data, updateData }) {
|
||||
const classes = useStyles();
|
||||
|
||||
useEffect(() => {
|
||||
api.get(`${host}/query?query={ImageListWithLatestTag(){Name%20Latest%20Description%20Vendor%20Licenses%20Labels%20Size%20LastUpdated}}`)
|
||||
api.get(`${host}${URL.imageList}`)
|
||||
.then(response => {
|
||||
if (response.data && response.data.data) {
|
||||
let imageList = response.data.data.ImageListWithLatestTag;
|
||||
@ -49,15 +54,16 @@ function Explore ({ keywords, data, updateData }) {
|
||||
description: image.Description,
|
||||
licenses: image.Licenses,
|
||||
size: image.Size,
|
||||
vendor: image.Vendor
|
||||
vendor: image.Vendor,
|
||||
lastUpdated: image.LastUpdated
|
||||
};
|
||||
});
|
||||
updateData(imagesData);
|
||||
setIsLoading(false);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
})
|
||||
},[])
|
||||
|
||||
@ -80,10 +86,10 @@ function Explore ({ keywords, data, updateData }) {
|
||||
|
||||
const filterStr = keywords && keywords.toLocaleLowerCase();
|
||||
|
||||
const renderImages = () => {
|
||||
const renderRepoCards = () => {
|
||||
return filteredData && filteredData.map((item, index) => {
|
||||
return (
|
||||
<ImageTile
|
||||
<RepoCard
|
||||
name={item.name}
|
||||
version={item.latestVersion}
|
||||
description={item.description}
|
||||
@ -93,6 +99,7 @@ function Explore ({ keywords, data, updateData }) {
|
||||
licenses={item.licenses}
|
||||
key={index}
|
||||
data={item}
|
||||
lastUpdated={item.lastUpdated}
|
||||
shown={true}
|
||||
/>
|
||||
);
|
||||
@ -112,12 +119,19 @@ function Explore ({ keywords, data, updateData }) {
|
||||
</Grid>
|
||||
) : (
|
||||
<Grid container className={classes.gridWrapper}>
|
||||
<Grid item xs={12}>
|
||||
<Stack direction="row" className={classes.resultsRow}>
|
||||
<Typography variant="body2">Results {filteredData.length}</Typography>
|
||||
<FormControl sx={{m:'1', minWidth:"75px"}}>
|
||||
<InputLabel>Sort</InputLabel>
|
||||
<Select label="Sort">
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Stack>
|
||||
<div style={{marginTop: 20}}>
|
||||
<div>
|
||||
<Typography className={classes.exploreText}>{`Displaying ${filteredData.length} of ${filteredData.length} packages served from ${host}...`}</Typography>
|
||||
<div style={{marginTop: 20}}>{renderImages()}</div>
|
||||
</div>
|
||||
<Stack direction="column" spacing={2}>{renderRepoCards()}</Stack>
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
@ -65,7 +65,6 @@ 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);
|
||||
@ -93,7 +92,7 @@ function Header({ updateKeywords }) {
|
||||
// };
|
||||
|
||||
return (
|
||||
<AppBar position="fixed">
|
||||
<AppBar sx={{position:"sticky"}}>
|
||||
<Toolbar className={classes.header}>
|
||||
<div>
|
||||
<Link to="/home" className={classes.icons}>
|
||||
|
@ -7,10 +7,10 @@ import axios from 'axios';
|
||||
|
||||
// components
|
||||
import Header from './Header.jsx'
|
||||
import ImageTile from './ImageTile.jsx'
|
||||
import RepoCard from './RepoCard.jsx'
|
||||
import Tags from './Tags.jsx'
|
||||
import {Container, Box, Grid} from '@mui/material';
|
||||
|
||||
import { URL } from '../constants';
|
||||
import makeStyles from '@mui/styles/makeStyles';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
@ -58,7 +58,7 @@ function ImageDetails (props) {
|
||||
}
|
||||
};
|
||||
|
||||
axios.get(`${host}/query?query={ExpandedRepoInfo(repo:\%22${name}\%22){Manifests%20{Digest%20Tag%20Layers%20{Size%20Digest}}}}`, cfg)
|
||||
axios.get(`${host}${URL.imageList}`, cfg)
|
||||
.then(response => {
|
||||
if (response.data && response.data.data) {
|
||||
let imageList = response.data.data.ExpandedRepoInfo;
|
||||
@ -85,7 +85,7 @@ function ImageDetails (props) {
|
||||
<Grid item md={1} ></Grid>
|
||||
<Grid item md={10}>
|
||||
<Box>
|
||||
<ImageTile className={classes.tile}
|
||||
<RepoCard className={classes.tile}
|
||||
name={myData.name}
|
||||
version={myData.latestVersion}
|
||||
description={myData.description}
|
||||
|
@ -1,96 +0,0 @@
|
||||
// react global
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
// utility
|
||||
|
||||
// components
|
||||
import {Card, CardActionArea, CardMedia, CardContent, Typography} from '@mui/material';
|
||||
import VerifiedUserIcon from '@mui/icons-material/VerifiedUser';
|
||||
|
||||
import makeStyles from '@mui/styles/makeStyles';
|
||||
import avatar from '../avatar.svg';
|
||||
import React from "react";
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
card: {
|
||||
marginBottom: 2,
|
||||
},
|
||||
cardLg: {
|
||||
marginBottom: 2,
|
||||
height: 200,
|
||||
},
|
||||
avatar: {
|
||||
objectFit: "contain",
|
||||
},
|
||||
cardBtn: {
|
||||
height: "100%",
|
||||
},
|
||||
media: {
|
||||
padding: 2,
|
||||
maxWidth: 150,
|
||||
borderRadius: '50px',
|
||||
marginTop: 20,
|
||||
},
|
||||
mediaLg: {
|
||||
maxWidth: 220,
|
||||
borderRadius: '50px',
|
||||
},
|
||||
content: {
|
||||
textAlign: "left",
|
||||
color: "#606060",
|
||||
},
|
||||
signedBadge: {
|
||||
color: '#9ccc65',
|
||||
height: '22px',
|
||||
width: '22px',
|
||||
marginLeft: 10,
|
||||
}
|
||||
}));
|
||||
|
||||
function ImageTile(props) {
|
||||
const classes = useStyles();
|
||||
const {name, version, vendor, shown} = props;
|
||||
|
||||
let style = {};
|
||||
if (!shown) {
|
||||
style = {display: 'none'};
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={style}>
|
||||
<Link to={`/image/${name}`} state={{data: props}} className={props.size === "lg" ? 'card-link' : ''}>
|
||||
<Card variant="outlined" className={props.size === "lg" ? classes.cardLg : classes.card}>
|
||||
<CardActionArea className={classes.cardBtn}>
|
||||
<div style={{display: 'flex'}}>
|
||||
<CardMedia classes={{
|
||||
root: props.size === "lg" ? classes.mediaLg : classes.media,
|
||||
img: classes.avatar,
|
||||
}}
|
||||
component="img"
|
||||
height= {props.size === "lg" ? 130 : 80}
|
||||
image={avatar}
|
||||
/>
|
||||
<CardContent className={classes.content}>
|
||||
<Typography variant="h5" component="div">
|
||||
{name}
|
||||
<VerifiedUserIcon className={classes.signedBadge}/>
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: 12 }} gutterBottom>
|
||||
{vendor || 'vendor'}
|
||||
</Typography>
|
||||
<Typography sx={{ mb: 1.5 }}>
|
||||
{version}
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
{name + " is a linux distribution that's composed entirely of free and open source software."}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</div>
|
||||
</CardActionArea>
|
||||
</Card>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ImageTile;
|
138
src/components/RepoCard.jsx
Normal file
138
src/components/RepoCard.jsx
Normal file
@ -0,0 +1,138 @@
|
||||
// react global
|
||||
import React from "react";
|
||||
import {useNavigate} from "react-router-dom";
|
||||
|
||||
// utility
|
||||
import {DateTime} from 'luxon';
|
||||
// components
|
||||
import {Card, CardActionArea, CardMedia, CardContent, Typography, Stack, Chip, Box, Grid} from '@mui/material';
|
||||
import CheckCircleOutlineOutlinedIcon from '@mui/icons-material/CheckCircleOutlineOutlined';
|
||||
import BookmarkIcon from '@mui/icons-material/Bookmark';
|
||||
import makeStyles from '@mui/styles/makeStyles';
|
||||
|
||||
// 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",
|
||||
padding: "2% 3% 2% 3%"
|
||||
},
|
||||
signedBadge: {
|
||||
color: '#9ccc65',
|
||||
height: '22px',
|
||||
width: '22px',
|
||||
marginLeft: 10,
|
||||
}
|
||||
}));
|
||||
|
||||
function RepoCard(props) {
|
||||
const classes = useStyles();
|
||||
const navigate = useNavigate();
|
||||
const {name, vendor, description, lastUpdated, downloads, rating} = props;
|
||||
|
||||
const goToCard = () => {
|
||||
navigate(`/image/${name}`);
|
||||
}
|
||||
|
||||
const verifiedCheck = () => {
|
||||
return (<CheckCircleOutlineOutlinedIcon sx={{color:"#388E3C!important"}}/>);
|
||||
}
|
||||
|
||||
const platformChips = () => {
|
||||
// if platforms not received, mock data
|
||||
const platforms = props.platforms || ["Windows","PowerPC64LE","IBM Z","Linux"];
|
||||
return platforms.map((platform, index) => (
|
||||
<Chip key={index} label={platform} sx={{backgroundColor:"#EDE7F6", color: "#311B92"}}/>
|
||||
));
|
||||
}
|
||||
|
||||
const getVendorLastPublish = () => {
|
||||
const lastDate = lastUpdated? DateTime.fromISO(lastUpdated) : DateTime.now().minus({days:1});
|
||||
return `${vendor || 'andrewc'} • published ${lastDate.toFormat('MM.d.yy')} • ${lastDate.toRelative({unit:'days'})}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<Card variant="outlined" className={classes.card}>
|
||||
<CardActionArea onClick={() => goToCard()} className={classes.cardBtn}>
|
||||
<CardContent className={classes.content}>
|
||||
<Grid container>
|
||||
<Grid item xs={10}>
|
||||
<Stack alignItems="center" direction="row" spacing={2}>
|
||||
<CardMedia classes={{
|
||||
root: classes.media,
|
||||
img: classes.avatar,
|
||||
}}
|
||||
component="img"
|
||||
image={randomImage()}
|
||||
alt="icon"
|
||||
/>
|
||||
<Typography variant="h5" component="div">
|
||||
{name}
|
||||
</Typography>
|
||||
<Chip label="Verified license" sx={{backgroundColor:"#E8F5E9", color:"#388E3C"}} variant="filled" onDelete={() => {return}} deleteIcon={verifiedCheck()}/>
|
||||
</Stack>
|
||||
<Typography pt={1} sx={{ fontSize: 12 }} gutterBottom>
|
||||
{description || 'The complete solution for node.js command-line programs'}
|
||||
</Typography>
|
||||
<Stack alignItems="center" direction="row" spacing={2} pt={1}>
|
||||
{platformChips()}
|
||||
</Stack>
|
||||
<Typography variant="body2" pt={1}>
|
||||
{getVendorLastPublish()}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={2} >
|
||||
<Stack justifyContent="end">
|
||||
<Typography variant="body2">Downloads • {downloads || '-'}</Typography>
|
||||
<Typography variant="body2">Rating • {rating || '-'}</Typography>
|
||||
<BookmarkIcon sx={{marginTop:"55%", marginLeft:"70%"}}/>
|
||||
</Stack>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</CardActionArea>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default RepoCard;
|
@ -4,21 +4,21 @@ import Header from '../components/Header.jsx'
|
||||
import Rightbar from '../components/Rightbar.jsx'
|
||||
|
||||
import makeStyles from '@mui/styles/makeStyles';
|
||||
import {Container, Grid} from '@mui/material';
|
||||
import {Container, Grid, Stack} from '@mui/material';
|
||||
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
container: {
|
||||
paddingTop: 5,
|
||||
paddingBottom: 5,
|
||||
height: '100vh',
|
||||
height: '100%'
|
||||
},
|
||||
gridWrapper: {
|
||||
backgroundColor: "#fff",
|
||||
// backgroundColor: "#fff",
|
||||
border: "1px #f2f2f2 dashed",
|
||||
},
|
||||
pageWrapper: {
|
||||
|
||||
height:"100%"
|
||||
},
|
||||
tile: {
|
||||
width: '100%',
|
||||
@ -29,16 +29,16 @@ function HomePage({ data, updateData, keywords, updateKeywords }) {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<div className={classes.pageWrapper}>
|
||||
<Stack className={classes.pageWrapper} direction="column">
|
||||
<Header updateKeywords={updateKeywords}></Header>
|
||||
<Container maxWidth="md" className={classes.container}>
|
||||
<Container maxWidth="md" className={classes.container} >
|
||||
<Grid container className={classes.gridWrapper}>
|
||||
<Grid item className={classes.tile}>
|
||||
<Rightbar keywords={keywords} data={data} updateData={updateData}/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Container>
|
||||
</div>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user