Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Add: improved signin/signup, dashboard flows #13

Merged
merged 2 commits into from
Oct 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"antd": "^4.16.13",
"axios": "^0.21.1",
"dayjs": "^1.10.7",
"jwt-decode": "^3.1.2",
"notistack": "^1.0.9",
"react": "^17.0.2",
"react-dom": "^17.0.2",
Expand Down
75 changes: 43 additions & 32 deletions src/components/card.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,49 @@
import { Card, Tooltip } from 'antd';
import {Card, Tooltip, Typography} from 'antd';
import { Link } from "react-router-dom";
import Text from "antd/es/typography/Text";

export const Tile = ({repoName, author, updatedAt}) => {
return (
<div
style={{background: '#ccd7e3', width: "90%", borderRadius: 8, boxShadow: "0.7px 1.4px 1.4px hsl(0deg 0% 0% / 0.48)", margin: "0.5% 0"}}>
<Card
hoverable
headStyle={{background: 'rgba(204,215,227,0.61)', fontWeight: "bold"}}
title={author+"/"+repoName}
bordered={true}
style={{ width: "100%", borderRadius: 8}}
extra={(
<div>
<Text style={{marginRight: "12px"}} copyable={{
text: `docker pull ${author}/${repoName}`,
tooltips: [<Tooltip>copy pull command</Tooltip>]
}}
/>
<span/>
<Link style={{fontWeight: "bold"}} to={`/details/${author}/${repoName}`}>More</Link>
</div>
)}
>
<p>Author: {author}</p>
<p>Updated At: {updatedAt}</p>
</Card>
</div>
)
export const Tile = ({ repoName, author, updatedAt }) => {
return (
<div
style={{ background: '#ccd7e3', width: "90%", borderRadius: 8, boxShadow: "0.7px 1.4px 1.4px hsl(0deg 0% 0% / 0.48)", margin: "0.5% 0" }}>
<Card
hoverable
headStyle={{ background: 'rgba(204,215,227,0.61)', fontWeight: "bold" }}
title={author + "/" + repoName}
bordered={true}
style={{ width: "100%", borderRadius: 8 }}
extra={(
<div>
<Text style={{ marginRight: "12px" }} copyable={{
text: `docker pull ${author}/${repoName}`,
tooltips: [<Tooltip>copy pull command</Tooltip>]
}}
/>
<span />
<Link style={{ fontWeight: "bold" }} to={`/details/${author}/${repoName}`}>More</Link>
</div>
)}
>
<p>Author: {author}</p>
<p>Updated At: {updatedAt}</p>
</Card>
</div>
)
}

export const RenderTileList = ({data = []}) => {
return data.map((item,i) => {
return <Tile repoName={item.repoName} author={item.author} updatedAt={item.updatedAt} key={i}/>
})
export const RenderTileList = ({ data = [] }) => {
if (data && data.length > 0) {
return data.map((item, i) => {
if (item.Namespace !== "") {
return <Tile
repoName={item.Namespace.split('/')[1]}
author={item.Namespace.split('/')[0]}
updatedAt={new Date().toDateString()}
key={i}
/>
}
})
} else {
return <Typography.Title level={3}>Nothing to see here :(</Typography.Title>
}
}
107 changes: 59 additions & 48 deletions src/components/menu.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,71 @@
import {Menu} from "antd";
import { Button, Menu } from "antd";
import parachute from "../styles/pictures/parachute.png";

import Complete from "./autocomplete";
import {UserOutlined, ArrowUpOutlined } from "@ant-design/icons";
import { UserOutlined, ArrowUpOutlined } from "@ant-design/icons";
import React from "react";
import {Link} from "react-router-dom";
import { Link } from "react-router-dom";
import { useHistory } from "react-router";

const styles = {
border: {
borderBottomColor: "red",
fontWeight: "bold",
"&:hover": {
backgroundColor: "#fff !important",
borderColor: "#fff !important",
color: "pink",
},
"border": 'none'
},
autoComplete: {
width: "40%",
paddingBottom: "0.5%"
},
menuStyle: {
display:"flex",
justifyContent:"space-between",
alignItems: "center",
backgroundColor: "rgba(152,171,196,0.98)",
"&:hover": {
color: "pink"
}
}

border: {
borderBottomColor: "red",
fontWeight: "bold",
border: 'none'
},
autoComplete: {
width: "35%",
paddingBottom: "0.5%"
},
menuStyle: {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
backgroundColor: "rgba(152,171,196,0.98)",
},
navButtonStyle: {
color: "black",
fontWeight: 600,
}
}

const NavBar = () => {
return <Menu style={styles.menuStyle} mode="horizontal">
<Menu.Item style={styles.border} key="openregistry" icon={<img src={parachute} style={{height:50}} alt={""}/>}>
<Link to="/repositories">OpenRegistry</Link>
</Menu.Item>
<Menu.Item style={styles.autoComplete} key="Search">
<Complete/>
</Menu.Item>
<Menu.Item style={styles.border} key="Repositories">
<Link to="/repositories">Repositories</Link>
</Menu.Item>
<Menu.Item style={styles.border} key="Explore">
<Link to="/explore">Explore</Link>
</Menu.Item>
<Menu.Item style={styles.border} key="Help" icon={<ArrowUpOutlined style={{ transform: "rotate(45deg)" }} />}>
<a target="_blank" href={"https://blog.openregistry.dev"}>Blog</a>
</Menu.Item>
<Menu.Item style={styles.border} key="log-out" icon={<UserOutlined/>}>
<Link to="/">Log Out</Link>
</Menu.Item>

</Menu>
const loc = useHistory();

const logOut = () => {
localStorage.clear()
loc.push('/')
}


return <Menu style={styles.menuStyle} mode="horizontal">
<Menu.Item style={styles.border} key="openregistry" icon={<img src={parachute} style={{ height: 50 }} alt={""} />}>
<Button size="small" type="link" style={styles.navButtonStyle} onClick={() => loc.push('/repositories')}>OpenRegistry</Button>
</Menu.Item>
<Menu.Item style={styles.autoComplete} key="Search">
<Complete />
</Menu.Item>
<Menu.Item style={styles.border} key="Repositories">
<Button size="small" type="link" onClick={() => loc.push('/repositories')} style={styles.navButtonStyle}>Repositories</Button>
</Menu.Item>
<Menu.Item style={styles.border} key="Explore">
<Button size="small" type="link" onClick={() => loc.push('/explore')} style={styles.navButtonStyle}>Explore</Button>
</Menu.Item>
<Menu.Item style={styles.border} key="Help">
<Button
size="small"
icon={<ArrowUpOutlined style={{ transform: "rotate(45deg)" }} />}
type="link"
onClick={() => window.open("https://blog.openregistry.dev")}
style={styles.navButtonStyle}
>
Blog
</Button>
</Menu.Item>
<Menu.Item style={styles.border} key="log-out">
<Button size="small" icon={<UserOutlined />} type="link" onClick={logOut} style={styles.navButtonStyle}>Log Out</Button>
</Menu.Item>
</Menu>

}

Expand Down
98 changes: 69 additions & 29 deletions src/components/signin.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import React, { useState } from "react";
import '../styles/landingpage.css'
import { OutlinedButton, SolidButton, SolidButton2 } from "./buttons";
import { TxtField } from "./inputfield"
import { Form, Input, Button, Typography, Spin } from 'antd';
import { LoadingOutlined, CheckCircleTwoTone, CloseCircleOutlined } from '@ant-design/icons';
import { useHistory, useLocation } from "react-router";
import { Form, Input, Button, Typography, message, Alert } from 'antd';
import { LoadingOutlined, CheckCircleTwoTone, CloseCircleOutlined, } from '@ant-design/icons';
import { useHistory, } from "react-router";
import axios from 'axios';

const SignIn = ({ handleSignUp, handleModalClose }) => {
message.config({
icon: null,
})

const SignIn = ({ handleSignUp, handleModalClose, }) => {
const [showVerifyLoader, setShowVerifyLoader] = useState(false)
const [emailVerified, setEmailVerified] = useState(false)
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [showLoader, setShowLoader] = useState(false);
const [showNotification, setShowNotification] = useState(false);
const [signInError, setSignInError] = useState('');

let loc = useHistory()
const SignIn = () => {
setTimeout(() => {
loc.push("/repositories")
}, 2000)
}

const handleCancel = () => {

const handleEmail = (input) => {
setEmail(input)
}
const antIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />;

const handlePassword = (input) => {
setPassword(input)
}

const handleVerifyEmail = () => {
setShowVerifyLoader(true)
Expand All @@ -31,21 +36,43 @@ const SignIn = ({ handleSignUp, handleModalClose }) => {
}, 2000)
}

const showEmailVerification = () => {
if (!showVerifyLoader) {
return <Button onClick={handleVerifyEmail} >Verify</Button>
} else if (emailVerified) {
return <CheckCircleTwoTone twoToneColor="#52c41a" />
} else {
return <CloseCircleOutlined twoToneColor="red" />
const notify = (kind, msg) => {
setShowNotification(false)
return message[kind]({
content: <Alert
message={msg}
type={kind}
closable={false}
icon={null}
/>,
duration: 2,
})
}

const handleUserSignin = () => {
setShowLoader(true)
const body = {
email: email,
password: password,
}

axios.post(`${process.env.REACT_APP_API_BASE_URL}/auth/signin`, body).then(res => {
localStorage.setItem('token', res.data.token)
localStorage.setItem('issued_at', res.data.issued_at)
localStorage.setItem('expires_in', res.data.expires_in)
setShowLoader(false)
loc.push('/repositories')
}).catch(err => {
setShowLoader(false)
setSignInError(err.response.data.error)
setShowNotification(true)
})
}

const [form] = Form.useForm();

return (
<div
style={{ borderRadius: 12, }}
>
<div style={{ borderRadius: 12, }} >
<Form
layout="vertical"
form={form}
Expand All @@ -54,7 +81,7 @@ const SignIn = ({ handleSignUp, handleModalClose }) => {
style={{ borderRadius: 12, display: "flex", flexDirection: "column", justifyContent: "center", padding: "0 5%" }}
>
<Form.Item>
<Typography.Title style={{ width: "100%", display: "flex", justifyContent: "center" }} level={2}>Sign up for OpenRegistry</Typography.Title>
<Typography.Title style={{ width: "100%", display: "flex", justifyContent: "center" }} level={2}>Sign in to OpenRegistry</Typography.Title>
</Form.Item>
<Form.Item
style={{ fontWeight: "bold" }}
Expand All @@ -66,7 +93,12 @@ const SignIn = ({ handleSignUp, handleModalClose }) => {
message: "email cannot be empty",
}
]}>
<Input type="email" placeholder="email" />
<Input
type="email"
value={email}
onChange={(e) => handleEmail(e.target.value)}
placeholder="email/username"
/>
</Form.Item>
<Form.Item
label={"Password"}
Expand All @@ -78,13 +110,20 @@ const SignIn = ({ handleSignUp, handleModalClose }) => {
message: "invalid password",
}
]}>
<Input.Password placeholder="password" />
<Input.Password
value={password}
onChange={(e) => handlePassword(e.target.value)}
placeholder="password"
/>
</Form.Item>
<Form.Item {...tailLayout}>
<Button
onClick={() => handleSignUp()}
onClick={handleUserSignin}
icon={showLoader ? <LoadingOutlined /> : null}
style={{ marginRight: "2%", borderRadius: 8, fontWeight: "bold" }} type={"primary"} htmlType={"submit"}>
Sign In
<Typography.Text style={{ fontWeight: "bold", color: "#fff" }}>
Sign In
</Typography.Text>
</Button>
<Button
style={{ marginRight: "2%", borderRadius: 8 }}
Expand All @@ -96,6 +135,7 @@ const SignIn = ({ handleSignUp, handleModalClose }) => {
</Typography.Text>
</Button>
</Form.Item>
{showNotification ? notify('error', signInError) : null}
{
// <Form.Item {...tailLayout}>
// <Typography.Text>
Expand Down
Loading