Skip to content
Open
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
31 changes: 31 additions & 0 deletions SOLUTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
This file will only countain some thought process, decision making and little remarks. It's a quick ready and I highly recommend it.

1. Overall structure of the project and package.json indicates that react is obviously fine to use. I read that it was allowed at the source repo, but "allowed" didn't
really convince me that I could 100% use it. Being a next.js app I also know right away that I won't have to bother with routing set up. Cool stuff!

2. Let's run it. Yarn dev? Working fine, let's go.

3. I chose "Billing profile details". The page is divided into two main sections.

SECTION A

.Brand logo
.Avatar + user info
.Routing - Just a list of strings that match a icon.

SECTION B

.Title
.3 tables - Mainly the last two look pretty identical, one component should do the trick for both.

There are some details that have to be taken into account, and I am pretty happy with the chosen page because altought it's very simple, there is also some depth to it.

4. Just noticed table rows have what seem to be a 1px border, I never get these right.

5. Not quite sure if I should just go with simple css or if using tailwind is seen as a bonus. I'm going for the later.

6. The figma design seems to be some pixels off here and there, like the avatar having a left margin of 63px and the list below 64px. Not very relevant, but I'll assume that the website doesn't have to be exactly pixel perfect.

7. /Components folder should be at root level. Some people use it on /pages and this drastically increases build time.

8. Vercel link: https://lexir-io-challenge-bay.vercel.app/
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@
"lint": "next lint"
},
"dependencies": {
"autoprefixer": "^10.4.8",
"next": "12.2.5",
"postcss": "^8.4.16",
"react": "18.2.0",
"react-dom": "18.2.0"
"react-dom": "18.2.0",
"tailwindcss": "^3.1.8"
},
"devDependencies": {
"@types/node": "^18.7.13",
Expand Down
6 changes: 6 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
41 changes: 41 additions & 0 deletions src/components/DashboardRoutes/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import Link from "next/link";
import Image from "next/image";
import { useRouter } from "next/router";

interface routes {
name: string;
path: string;
key: number;
icon: string;
}

export default function Routes({
routes,
spacing,
}: {
routes: routes[];
spacing: string;
}) {
const router = useRouter();

return (
<ul className="flex flex-grow-1 flex-col h-full w-full mt-[80px]">
{routes.map((route, index) => (
<Link key={route.key} href={route.path}>
<div
className={
router.pathname == route.path
? `flex items-center pl-[27px] pt-[16px] pb-[16px] bg-secondary-100 hover:cursor-pointer`
: `flex items-center pl-[27px] pt-[16px] pb-[16px] hover:cursor-pointer hover:bg-secondary-100`
}
>
<Image src={route.icon} />
<li key={route.key} className="ml-[15px] text-primary-700 ">
<p>{route.name}</p>
</li>
</div>
</Link>
))}
</ul>
);
}
103 changes: 103 additions & 0 deletions src/components/Layout/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import Image from "next/image";
import Link from "next/link";
import UserAvatar from "src/components/UserAvatar";
import Leandro from "src/public/Leandro.png";
import Routes from "src/components/DashboardRoutes";
import {
Card,
Customers,
Dashboard,
Details,
Logout,
Orders,
ProductBox,
ProductTag,
} from "src/public/svgs";
import LexirLogo from "src/public/logo.png";

interface routes {
name: string;
path: string;
icon: string;
key: number;
}

const routes: routes[] = [
{
name: "Dashboard",
path: "/dashboard",
icon: Dashboard,
key: 1,
},
{
name: "Brands",
path: "/brands",
icon: ProductTag,
key: 2,
},
{
name: "Products",
path: "/products",
icon: ProductBox,
key: 3,
},
{
name: "Customers",
path: "/customers",
icon: Customers,
key: 4,
},
{
name: "Orders",
path: "/orders",
icon: Orders,
key: 5,
},
{
name: "Billing Profile",
path: "/",
icon: Card,
key: 6,
},
{
name: "Account details",
path: "/details",
icon: Details,
key: 7,
},
{
name: "Logout",
path: "/logout",
icon: Logout,
key: 8,
},
];

export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div className="w-screen h-full flex ">
<div className="py-[60px] w-[37.5%] ">
<div className="flex flex-col items-center px-[30px] ">
<Link href="/">
<Image
width={145}
height={34}
className="hover:cursor-pointer "
src={LexirLogo}
/>
</Link>
<UserAvatar
image={Leandro}
name="Leandro Alves"
company="Company Name"
className="rounded-full"
width="66px"
height="66px"
/>
<Routes spacing="4" routes={routes} />
</div>
</div>
{children}
</div>
);
}
40 changes: 40 additions & 0 deletions src/components/UserAvatar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Image, { StaticImageData } from "next/image";
import DefaultImage from "src/public/defaultUserImage.png";

import { useState } from "react";

export default function UserAvatar({
width,
height,
image,
name,
company,
className,
}: {
width: string;
height: string;
image: string | StaticImageData;
name: string;
company: string;
className: string;
}) {
const [imageSource, setImageSource] = useState(DefaultImage);
return (
<div className="flex mt-[100px] items-center">
<Image
src={image}
alt="user avatar"
width={width}
height={height}
className={className}
onError={() => {
setImageSource(DefaultImage);
}}
/>
<div className="flex ml-[11px] flex-col">
<p className="text-primary-700 text-[22px] font-bold">{name}</p>
<p className="text-primary-100">{company}</p>
</div>
</div>
);
}
6 changes: 6 additions & 0 deletions src/data/dummy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export let userDummy = {
"Credit Card": "Mastercard ending in 3887 expires on 4/23",
Name: "Leandro Alves",
Address: "Agras Street 8798, 4000-458 Porto, Portugal ",
"Next Billing": "9 April 2023",
};
2 changes: 1 addition & 1 deletion src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import "../styles/globals.css";
import "tailwindcss/tailwind.css";

function MyApp({ Component, pageProps }: any) {
return <Component {...pageProps} />;
Expand Down
35 changes: 35 additions & 0 deletions src/pages/_document.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import Document, { Html, Head, Main, NextScript } from "next/document";
import { useDebugValue } from "react";

class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);

return initialProps;
}

render() {
return (
<Html>
<Head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossOrigin="true"
/>
<link
href="https://fonts.googleapis.com/css2?family=Lato:wght@400;700&family=Source+Serif+Pro:wght@400;600;700&display=swap"
rel="stylesheet"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}

export default MyDocument;
Loading