Commit 1abc5ed2 authored by Alex Segers's avatar Alex Segers

🔀 [AFP-135] Merge branch 'dev' of...

🔀  [AFP-135] Merge branch 'dev' of https://gitlab.mynisum.com/ascend/order-management-react into AFP-135 (@asegers)
parents d5f3e16d 592cb41f
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "order-management-client", "name": "order-management-client",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"proxy": "http://localhost:8080", "proxy": "http://localhost:4",
"dependencies": { "dependencies": {
"@chakra-ui/icons": "^1.0.13", "@chakra-ui/icons": "^1.0.13",
"@chakra-ui/react": "^1.6.0", "@chakra-ui/react": "^1.6.0",
......
import React, { useMemo} from 'react' import React, { useMemo, useRef, useState, useEffect } from 'react'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import {useGoogleAuth} from 'hooks' import {useGoogleAuth} from 'hooks'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faUser } from '@fortawesome/free-solid-svg-icons' import { faUser } from '@fortawesome/free-solid-svg-icons'
import { Box, Heading, Flex, Spacer, Button, Image, Avatar } from "@chakra-ui/react" import { AccountPage } from 'pages'
import { Box, Heading, Flex, Spacer, Button, Image, Avatar, HStack, Input } from "@chakra-ui/react"
import Logo from '../img/logo.png' import Logo from '../img/logo.png'
import {
Drawer,
DrawerBody,
DrawerHeader,
DrawerOverlay,
DrawerContent,
DrawerCloseButton,
useDisclosure
} from "@chakra-ui/react"
import {
Menu,
MenuButton,
MenuList,
MenuItem,
MenuItemOption,
MenuGroup,
MenuOptionGroup,
MenuIcon,
MenuCommand,
MenuDivider,
} from "@chakra-ui/react"
import { ChevronDownIcon } from '@chakra-ui/icons'
const Nav = () => { const Nav = () => {
const { isSignedIn, signOut, signIn, manager } = useGoogleAuth(); const { isSignedIn, signOut, signIn, manager } = useGoogleAuth();
const handleAuth = () => { isSignedIn ? signOut() : signIn();} const handleAuth = () => { isSignedIn ? signOut() : signIn();}
const loginIcon = faUser
const authLinkText = useMemo(() => isSignedIn ? "Logout" : "Login", [isSignedIn]); const authLinkText = useMemo(() => isSignedIn ? "Logout" : "Login", [isSignedIn]);
const { isOpen, onOpen, onClose } = useDisclosure();
const btnRef = useRef<HTMLButtonElement>(null);
const userName = isSignedIn ? <p>{manager.firstName} {manager.lastName}</p> : null
const userIcon = isSignedIn ? const userIcon = isSignedIn ?
<Avatar name={manager.firstName + " " + manager.lastName} boxSize="40px" borderRadius="full" src={manager.imageUrl} alt="profile"/> : null <Avatar boxSize="40px" borderRadius="full" src={manager.imageUrl} alt="profile"/> : <div>{authLinkText}</div>
return ( return (
<Flex className="header"> <Flex className="header" justifyContent="space-between">
<Box className="left-nav"> <Box >
<Link to="/"><Image src={Logo} alt="project logo" height="90%" width="80%" /></Link> <h1 className="header-title">Ascend Final Project</h1>
</Box>
<Box className="center-nav" display="-ms-inline-flexbox">
<HStack>
<Link to="/"><Image src={Logo} alt="project logo" className="logoImg"/></Link>
<h1>Order Management</h1>
{/* <Link to="/"><h1>Order Management</h1></Link> */}
</HStack>
</Box>
{/* <HStack className="right-nav" spacing="1px">
<Box><button onClick={handleAuth}>{authLinkText}</button></Box>
<Box><button ref={btnRef} onClick={onOpen}>{userIcon}</button></Box>
<Drawer
isOpen={isOpen}
placement="right"
onClose={onClose}
finalFocusRef={btnRef}
>
<DrawerOverlay />
<DrawerContent>
<DrawerCloseButton size="sm"/>
<DrawerHeader align="center" >User Account</DrawerHeader>
<DrawerBody>
<AccountPage />
</DrawerBody>
</DrawerContent>
</Drawer>
</HStack> */}
<Box >
<Menu>
<MenuButton rightIcon={<ChevronDownIcon />} onClick={onOpen} width="300px" className="right-nav">
<HStack>
<span>{userIcon}</span>
<span>{userName}</span>
{/* <span>{authLinkText}</span> */}
</HStack>
</MenuButton>
<MenuList>
<MenuItem color="black"><Link to="/orders">Orders</Link></MenuItem>
<MenuItem color="black"><Link to="/account">Account</Link></MenuItem>
<MenuItem color="black"><button onClick={handleAuth}>{authLinkText}</button></MenuItem>
</MenuList>
</Menu>
</Box> </Box>
<Spacer />
<Flex className="right-nav">
<Link className="nav-link" to="/account">{userIcon}</Link>
<Button
p={2}
size="sm"
color="white"
fontWeight="bold"
borderRadius="sm"
bgGradient="linear(to-r, teal.500,blue.500)"
_hover={{
bgGradient: "linear(to-r, blue.500, yellow.500)",
}}
><Link to="/orders">Orders</Link></Button>
<Button
p={2}
size="sm"
color="white"
fontWeight="bold"
borderRadius="sm"
bgGradient="linear(to-r, teal.500,blue.500)"
_hover={{
bgGradient: "linear(to-r, yellow.500, blue.500)",
}}
onClick={handleAuth}>{authLinkText}</Button>
</Flex>
</Flex> </Flex>
) )
} }
......
...@@ -21,7 +21,7 @@ const OrderDetails = (props: any) => { ...@@ -21,7 +21,7 @@ const OrderDetails = (props: any) => {
const status = props.status const status = props.status
return ( return (
<> <>
<Td><Link to={"/orders/" + orderNumber}>{orderNumber.slice(orderNumber.length - 7).toUpperCase()}</Link></Td> <Td><Link to={"/orders/" + orderNumber}>{orderNumber}</Link></Td>
<Td>{date}</Td> <Td>{date}</Td>
<Td>{status}</Td> <Td>{status}</Td>
</> </>
......
...@@ -23,12 +23,12 @@ const OrderShowDetails = (props: any) => { ...@@ -23,12 +23,12 @@ const OrderShowDetails = (props: any) => {
const itemMap = (items: Item[]) => { const itemMap = (items: Item[]) => {
return items.map((item: Item, idx: number) => { return items.map((item: Item, idx: number) => {
return ( return (
<tr key={idx}> <Tr key={idx} >
<Td >{item.itemId}</Td > <Td >{item.itemId}</Td >
<Td >{item.itemPrice}</Td > <Td >{item.itemPrice}</Td >
<Td >{item.itemQuantity}</Td > <Td >{item.itemQuantity}</Td >
<Td >{item.itemSku}</Td > <Td >{item.itemSku}</Td >
</tr> </Tr>
) )
}); });
} }
...@@ -37,19 +37,19 @@ const OrderShowDetails = (props: any) => { ...@@ -37,19 +37,19 @@ const OrderShowDetails = (props: any) => {
return ( return (
items ? items ?
<div className="table-div"> <Table variant="striped" colorScheme="messenger" size="lg">
<Table variant="striped" colorScheme="messenger" size="lg"> <Thead >
<Tbody> <Tr className="table-header" >
<Tr className="table-header"> <Th fontSize="21px" color="rgba(255, 166, 0, 0.897)">ID</Th>
<Th fontSize="22px" color="gray">ID</Th> <Th fontSize="21px" color="rgba(255, 166, 0, 0.897)">Price</Th>
<Th fontSize="22px" color="gray">Price</Th> <Th fontSize="21px" color="rgba(255, 166, 0, 0.897)">Quantity</Th>
<Th fontSize="22px" color="gray">Quantity</Th> <Th fontSize="21px" color="rgba(255, 166, 0, 0.897)">SKU</Th>
<Th fontSize="22px" color="gray">SKU</Th> </Tr>
</Tr> </Thead>
{itemDetails} <Tbody>
</Tbody> {itemDetails}
</Table> </Tbody>
</div> </Table>
: :
<div className="Order without items"> <div className="Order without items">
This order didn't contain any items. This order didn't contain any items.
......
src/img/logo.png

10.3 KB | W: | H:

src/img/logo.png

4.22 KB | W: | H:

src/img/logo.png
src/img/logo.png
src/img/logo.png
src/img/logo.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -15,46 +15,106 @@ code { ...@@ -15,46 +15,106 @@ code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
} }
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
}
.content {
min-height: calc(100vh - 70px);
}
/* homepage */ /* homepage */
.homepage { .homepage {
padding: 200px 0; padding: 200px 0;
} }
/* .svg-inline--fa {
display: inline-block;
font-size: 24px;
height: 1.7em;
overflow: visible;
vertical-align: -0.325em;
} */
/* header */ /* header */
.header { .header {
border-bottom: 1.5px solid orange; border-top: 1.5px solid rgba(80, 76, 69, 0.603);
background-color: #00567D;
height: 50px;
color: #EBEBEB;
}
.header-title {
margin-left: 70px;
margin-top: 10px;
}
.header h1 {
color: #EBEBEB;
}
.header span {
color: #EBEBEB;
}
.center-nav {
padding: 0 0 0 10px;
}
.center-nav p {
margin-left: -250px;
}
.logoImg {
width: 150px;
height: 45px;
} }
.left-nav { .left-nav Link {
padding: 10px 0px 0px 50px; color: red;
} }
.right-nav { .right-nav {
padding: 30px 120px 0px 0px; margin-top: 2.5px;
} }
.right-nav Button { /* .right-nav button {
background-color: rgb(235, 221, 178); background-color: transparent;
margin-right: 15px; margin-right: 15px;
margin-top: 4px; margin-top: 4px;
} */
/* .right-nav span {
margin-left: 10px;
margin-right: 25px;
font-weight: 600;
} */
.chakra-stack.right-nav.css-193rmy8 {
margin-bottom: 50%;
}
.chakra-menu__menu-button.css-59llwj {
/* margin-right: 500px; */
width: 250px;
} }
.nav-link { .nav-link {
margin-right: 15px; margin-right: 15px;
margin-left: 15px;
} }
...@@ -62,9 +122,45 @@ code { ...@@ -62,9 +122,45 @@ code {
/* body */ /* body */
.table-div { .content {
padding: 150px; flex: 1 0 auto;
padding-top: 80px; }
.search-div {
padding: 2px;
}
input[type=text] {
width: 220px;
border: 2px solid rgb(184, 180, 180);
border-radius: 4px;
font-size: 14px;
background-color: white;
background-image: url('./img/searchicon.png');
background-size: 18px;
background-position: 10px 8px;
background-repeat: no-repeat;
padding: 12px 20px 12px 40px;
transition: width 0.4s ease-in-out;
height: 35px;
}
input[type=text]:focus {
width: 100%;
}
.searchbar:focus {
outline: none;
}
.body-content-div {
padding: 120px;
padding-top: 20px;
} }
.index-table { .index-table {
...@@ -72,30 +168,53 @@ code { ...@@ -72,30 +168,53 @@ code {
padding: 0 10px 15px 10px; padding: 0 10px 15px 10px;
border-radius: 2px; border-radius: 2px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
padding-top: 10px;
} }
.show-div { .show-div {
padding: 80px 150px; padding: 80px 100px;
} }
.show-table { .show-table {
border: 1px solid rgb(110, 106, 106); border: 1px solid rgb(110, 106, 106);
/* padding: 0 10px 15px 10px; */ padding: 0 10px 15px 10px;
border-radius: 2px; border-radius: 2px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
} }
.table-header { .table-header {
background-color: rgba(228, 158, 67, 0.5); background-color: #00557ddc;
color: black;
} }
/* User Drawer */
.account {
padding: 40px 0;
border-top: 1px solid rgba(68, 64, 64, 0.363);
border-bottom: 1px solid rgba(68, 64, 64, 0.363);
}
/* .user-name {
padding-top: 3.5px;
} */
/* .chakra-stack__divider.css-vhtjkn {
height: -140px;
} */
/* footer */ /* footer */
.footer { .footer {
padding: 10px 0; padding: 5px 0;
border-top: 1.5px solid orange; border-bottom: 2.5px solid rgba(80, 76, 69, 0.603);
background-color: rgba(216, 130, 32, 0.404);
flex-shrink: 0;
font-size: 12px;
} }
\ No newline at end of file
import { Box, Avatar, Center } from '@chakra-ui/react' import { Box, Avatar, Center, VStack, StackDivider, Spacer, Flex } from '@chakra-ui/react'
import {useGoogleAuth} from 'hooks' import {useGoogleAuth} from 'hooks'
const AccountPage = () => { const AccountPage = () => {
const { manager } = useGoogleAuth(); const { manager } = useGoogleAuth();
return ( return (
<Center> <VStack className="account">
<Box> <Avatar name={manager.firstName + " " + manager.lastName} size="2xl" src={manager.imageUrl} alt="profile" />
<Box> <Box w="270px" >
<Avatar name={manager.firstName + " " + manager.lastName} size="2xl" src={manager.imageUrl} alt="profile" /> <VStack
</Box> divider={<StackDivider borderColor="gray.200" />}
<Box> spacing={4}
Email: {manager.email} align="center"
</Box> >
<Box> <Box h="5px" className="user-name">{manager.firstName} {manager.lastName}</Box>
First Name: {manager.firstName} <Box h="28px"
</Box> w="280px"
<Box> size="sm"
Last Name: {manager.lastName} align="center"
color="white"
fontWeight="bold"
borderRadius="md"
bgGradient="linear(to-r, teal.500,blue.500)"
// _hover={{
// bgGradient: "linear(to-r, blue.500, yellow.500)",
// }}
>{manager.email }
</Box> </Box>
</VStack>
</Box> </Box>
</Center> </VStack>
) )
} }
......
...@@ -19,11 +19,12 @@ const OrderIndexPage = () => { ...@@ -19,11 +19,12 @@ const OrderIndexPage = () => {
const [orderDetailsArr, setOrderDetailsArr] = useState<any>([]) const [orderDetailsArr, setOrderDetailsArr] = useState<any>([])
const orderDetailsArrCreator = (orders: Order[]) => { const orderDetailsArrCreator = (orders: Order[]) => {
return orders.map((order: Order, idx: any) => { return orders.map((order: Order, idx: any) => {
return <Tr key={idx}><OrderDetails return <Tr key={idx}>
date={new Date(order.orderCreatedAt).toLocaleDateString()} <OrderDetails
orderNumber={order.id} date={new Date(order.orderCreatedAt).toLocaleDateString()}
status={order.orderStatus} orderNumber={order.id}
/></Tr> status={order.orderStatus}/>
</Tr>
}) })
} }
...@@ -43,7 +44,7 @@ const OrderIndexPage = () => { ...@@ -43,7 +44,7 @@ const OrderIndexPage = () => {
useEffect(() => { useEffect(() => {
const newArray: Order[] = [] const newArray: Order[] = []
for (const ele of allOrders) { for (const ele of allOrders) {
if (ele.id.includes(searchInput)) { if (ele.id.includes(searchInput.toLowerCase())) {
newArray.push(ele) newArray.push(ele)
} }
} }
...@@ -56,24 +57,26 @@ const OrderIndexPage = () => { ...@@ -56,24 +57,26 @@ const OrderIndexPage = () => {
} }
return ( return (
<div className="table-div"> <div className="body-content-div">
<Input <div className="search-div">
type="text" <input
placeholder="Search by Order Number" type="text"
focusBorderColor="telegram.400" placeholder="Search Order Number"
value={searchInput} value={searchInput}
onChange={handleChange} onChange={handleChange}
onKeyDown={handleChange} onKeyDown={handleChange}
> className="searchbar"
</Input> >
<br/> </input>
</div>
<br/>
<div className="index-table"> <div className="index-table">
<Table variant="striped" colorScheme="messenger" size="sm"> <Table variant="striped" colorScheme="messenger" size="md">
<Thead> <Thead>
<Tr className="table-header"> <Tr className="table-header">
<Th fontSize="26px" color="gray">Order number</Th> <Th fontSize="24px" color="rgba(255, 166, 0, 0.897)">Order number</Th>
<Th fontSize="26px" color="gray">Order Date</Th> <Th fontSize="24px" color="rgba(255, 166, 0, 0.897)">Order Date</Th>
<Th fontSize="26px" color="gray">Order Status</Th> <Th fontSize="24px" color="rgba(255, 166, 0, 0.897)">Order Status</Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
......
...@@ -15,7 +15,7 @@ const OrderShowPage = (props: any) => { ...@@ -15,7 +15,7 @@ const OrderShowPage = (props: any) => {
// const { id } = useParams<any>(); // const { id } = useParams<any>();
// const { order } = useOrder(id) // const { order } = useOrder(id)
const location = props.match.params.id; const location = props.match.params.id;
const apiUrl = 'http://localhost:8080/api/orders/' + location; const apiUrl = 'http://localhost:8084/api/orders/' + location;
const [order, setOrder] = useState<Order>(); const [order, setOrder] = useState<Order>();
const [items, setItems] = useState<Item[]>() const [items, setItems] = useState<Item[]>()
...@@ -36,7 +36,7 @@ const OrderShowPage = (props: any) => { ...@@ -36,7 +36,7 @@ const OrderShowPage = (props: any) => {
<div className="show-div"> <div className="show-div">
<Flex justify="space-around"> <Flex justify="space-around">
<Box><strong>Order Date:</strong> {new Date(order.orderCreatedAt).toLocaleDateString()}</Box> <Box><strong>Order Date:</strong> {new Date(order.orderCreatedAt).toLocaleDateString()}</Box>
<Box><strong>Order Number:</strong> {order.id.slice(order.id.length - 7).toUpperCase()}</Box> <Box><strong>Order Number:</strong> {order.id}</Box>
<Box><strong>Order Status:</strong> {order.orderStatus}</Box> <Box><strong>Order Status:</strong> {order.orderStatus}</Box>
</Flex> </Flex>
<br/> <br/>
......
...@@ -11,17 +11,19 @@ const MainRouter: React.FC = () => { ...@@ -11,17 +11,19 @@ const MainRouter: React.FC = () => {
<StyleProvider> <StyleProvider>
<BrowserRouter> <BrowserRouter>
<GoogleAuthProvider> <GoogleAuthProvider>
<Nav /> <body>
<main> <Nav />
<Switch> <main className="content">
<PrivateRoute path="/account" component={AccountPage} /> <Switch>
<PublicRoute exact path="/" component={HomePage} /> <PrivateRoute path="/account" component={AccountPage} />
<PrivateRoute path="/orders/:id" component={OrderShowPage} /> <PublicRoute exact path="/" component={HomePage} />
<PrivateRoute path="/orders" component={OrderIndexPage} /> <PrivateRoute path="/orders/:id" component={OrderShowPage} />
{/* <Route component={NotFoundPage} /> */} <PrivateRoute path="/orders" component={OrderIndexPage} />
</Switch> {/* <Route component={NotFoundPage} /> */}
</main> </Switch>
<Footer /> </main>
<Footer />
</body>
</GoogleAuthProvider> </GoogleAuthProvider>
</BrowserRouter> </BrowserRouter>
......
...@@ -6,7 +6,7 @@ import { sleep } from 'utils' ...@@ -6,7 +6,7 @@ import { sleep } from 'utils'
const BASE_PATH = '/api/orders' const BASE_PATH = '/api/orders'
export const allOrders = () => { export const allOrders = () => {
const apiUrl = 'http://localhost:8080/api/orders'; const apiUrl = 'http://localhost:8084/api/orders';
return fetch(apiUrl).then((response) => response.json()) return fetch(apiUrl).then((response) => response.json())
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment