-
Notifications
You must be signed in to change notification settings - Fork 265
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'clean' of https://github.com/hngprojects/hng_boilerplat…
…e_nextjs into clean
- Loading branch information
Showing
40 changed files
with
1,638 additions
and
32 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
"use client"; | ||
|
||
import { Box, House, LucideProps, Mail, Settings, Users } from "lucide-react"; | ||
import Link from "next/link"; | ||
import { usePathname } from "next/navigation"; | ||
import { FC, ForwardRefExoticComponent, RefAttributes } from "react"; | ||
|
||
import DashboardLogo from "../logo"; | ||
|
||
const sideItems = [ | ||
{ | ||
route: "Dashboard", | ||
link: "/admin/dashboard", | ||
icon: House, | ||
id: "dashboard", | ||
}, | ||
{ | ||
route: "Products", | ||
link: "/admin/products", | ||
icon: Box, | ||
id: "products", | ||
}, | ||
{ | ||
route: "Users", | ||
link: "/admin/users", | ||
icon: Users, | ||
id: "users", | ||
}, | ||
{ | ||
route: "Email Templates", | ||
link: "/admin/email", | ||
icon: Mail, | ||
id: "email", | ||
}, | ||
{ | ||
route: "Squeeze Pages", | ||
link: "/admin/squeeze-pages", | ||
icon: Users, | ||
id: "squeeze", | ||
}, | ||
{ | ||
route: "Waitlist Page", | ||
link: "/admin/waitlist-page", | ||
icon: Mail, | ||
id: "waitlist", | ||
}, | ||
{ | ||
route: "Settings", | ||
link: "/admin/settings", | ||
icon: Settings, | ||
id: "settings", | ||
}, | ||
]; | ||
interface Iproperties { | ||
sideNavitems?: { | ||
route: string; | ||
link: string; | ||
icon: ForwardRefExoticComponent< | ||
Omit<LucideProps, "ref"> & RefAttributes<SVGSVGElement> | ||
>; | ||
id: string; | ||
}[]; | ||
currenPathName?: string; | ||
} | ||
const Sidebar: FC<Iproperties> = ({ | ||
sideNavitems = sideItems, | ||
currenPathName, | ||
}) => { | ||
const pathname = usePathname(); | ||
const currentPath = pathname?.split("/")[2]; | ||
return ( | ||
<div className="flex flex-col items-center justify-start border-r bg-muted/40 md:block md:px-4"> | ||
<DashboardLogo /> | ||
<section className="flex flex-col items-center gap-5 pt-6 md:items-stretch"> | ||
{sideNavitems.map((item, index) => ( | ||
<Link | ||
key={index} | ||
href={item.link} | ||
data-testid={item.id} | ||
role="sidebar-link" | ||
className={`${currenPathName || currentPath === item.id ? "bg-primary text-white" : "bg-transparent text-neutral-dark-2"} flex h-10 w-10 items-center justify-center gap-3 rounded-full px-2.5 py-4 transition-all duration-300 hover:bg-primary hover:text-white md:h-auto md:w-auto md:justify-start md:rounded-[8px]`} | ||
> | ||
<item.icon className="h-5 w-5" role="sidebar-icon" /> | ||
<span className="hidden md:block">{item.route}</span> | ||
</Link> | ||
))} | ||
</section> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Sidebar; |
83 changes: 83 additions & 0 deletions
83
src/app/(admin)/_components/layout/Sidebar/sidebar.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { Box, House, Mail, Settings, Users } from "lucide-react"; | ||
|
||
import { render, screen } from "~/test/utils"; | ||
import Sidebar from "./"; | ||
|
||
const sideItems = [ | ||
{ | ||
route: "Dashboard", | ||
link: "/admin/dashboard", | ||
icon: House, | ||
id: "dashboard", | ||
}, | ||
{ | ||
route: "Products", | ||
link: "/admin/products", | ||
icon: Box, | ||
id: "products", | ||
}, | ||
{ | ||
route: "Users", | ||
link: "/admin/users", | ||
icon: Users, | ||
id: "users", | ||
}, | ||
{ | ||
route: "Email Templates", | ||
link: "/admin/email", | ||
icon: Mail, | ||
id: "email", | ||
}, | ||
{ | ||
route: "Squeeze Pages", | ||
link: "/admin/squeeze-pages", | ||
icon: Users, | ||
id: "squeeze", | ||
}, | ||
{ | ||
route: "Waitlist Page", | ||
link: "/admin/waitlist-page", | ||
icon: Mail, | ||
id: "waitlist", | ||
}, | ||
{ | ||
route: "Settings", | ||
link: "/admin/settings", | ||
icon: Settings, | ||
id: "settings", | ||
}, | ||
]; | ||
|
||
describe("page tests", () => { | ||
const renderComponent = () => { | ||
render(<Sidebar sideNavitems={sideItems} currenPathName="dashboard" />); | ||
|
||
return { | ||
logo: screen.getByTestId("admin-logo"), | ||
logoText: screen.getByTestId("admin-logo-text"), | ||
dashboardlink: screen.getByTestId("dashboard"), | ||
}; | ||
}; | ||
it("side logo renders", () => { | ||
expect.assertions(2); | ||
|
||
const { logo, logoText } = renderComponent(); | ||
|
||
expect(logo).toBeInTheDocument(); | ||
expect(logoText).toBeInTheDocument(); | ||
}); | ||
|
||
it("renders all sidebar items", () => { | ||
expect.assertions(1); | ||
renderComponent(); | ||
expect(screen.getAllByRole("sidebar-link")).toHaveLength(sideItems.length); | ||
}); | ||
|
||
it("highlights active link", () => { | ||
expect.assertions(1); | ||
renderComponent(); | ||
expect(screen.getByTestId("dashboard")).toHaveClass( | ||
"bg-primary text-white", | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import Image from "next/image"; | ||
import Link from "next/link"; | ||
|
||
const DashboardLogo = () => { | ||
return ( | ||
<Link | ||
href="/" | ||
className="flex w-full max-w-[24px] items-center justify-center gap-2.5 py-[14px] md:justify-start" | ||
> | ||
<Image | ||
src="/logo/logo.png" | ||
alt="Hgn boiler plate logo" | ||
height={24} | ||
width={24} | ||
data-testid="admin-logo" | ||
className="h-full w-full object-contain" | ||
/> | ||
<span | ||
className="neutral-dark hidden text-2xl font-semibold md:block" | ||
data-testid="admin-logo-text" | ||
> | ||
Boilerplate | ||
</span> | ||
</Link> | ||
); | ||
}; | ||
|
||
export default DashboardLogo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 3 additions & 3 deletions
6
...n/_components/navbar/AdminNavbar.test.tsx → ..._components/layout/navbar/navbar.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { render } from "~/test/utils"; | ||
import Page from "./page"; | ||
|
||
describe("page tests", () => { | ||
it("should render correctly", () => { | ||
expect.assertions(1); | ||
|
||
render(<Page />); | ||
|
||
expect(true).toBeTruthy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
const page = () => { | ||
return <div>Admin dashboard</div>; | ||
}; | ||
|
||
export default page; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { FC, ReactNode } from "react"; | ||
|
||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs"; | ||
|
||
interface ITab { | ||
name: string; | ||
value: string; | ||
content: ReactNode; | ||
} | ||
|
||
interface IProperties { | ||
tabs: ITab[]; | ||
} | ||
|
||
const Toptab: FC<IProperties> = ({ tabs }) => { | ||
return ( | ||
<Tabs defaultValue={tabs[0].value} className="max-w-[670px]"> | ||
<TabsList className="mb-6 rounded-[8px] border-[1px] border-[#CBD5E1B2]/70 bg-transparent p-0"> | ||
{tabs?.map((tab, item) => { | ||
return ( | ||
<TabsTrigger | ||
data-testid="trigger-btn" | ||
key={item} | ||
value={tab.value} | ||
className="rounded-none bg-transparent text-sm text-[#8E8E93] data-[state=active]:bg-[#F6F7F9] data-[state=active]:text-primary" | ||
> | ||
{tab.name} | ||
</TabsTrigger> | ||
); | ||
})} | ||
</TabsList> | ||
{tabs?.map((tab, item) => { | ||
return ( | ||
<TabsContent | ||
data-testid="toptab-content" | ||
key={item} | ||
value={tab.value} | ||
className="w-auto" | ||
> | ||
{tab.content} | ||
</TabsContent> | ||
); | ||
})} | ||
</Tabs> | ||
); | ||
}; | ||
|
||
export default Toptab; |
74 changes: 74 additions & 0 deletions
74
src/app/(admin)/admin/email/_components/new-template/NewTemplate.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { render, screen } from "@testing-library/react"; | ||
import { CodeIcon, FileIcon, LucideProps } from "lucide-react"; | ||
import { ForwardRefExoticComponent } from "react"; | ||
|
||
import PageHeader from "../page-header"; | ||
import NewTemplate, { Options } from "./NewTemplate"; | ||
|
||
interface Option { | ||
title: string; | ||
description: string; | ||
icon: ForwardRefExoticComponent< | ||
Omit<LucideProps, "ref"> & React.RefAttributes<SVGSVGElement> | ||
>; | ||
link: string; | ||
} | ||
|
||
const options: Option[] = [ | ||
{ | ||
title: "Generate with HTML", | ||
description: | ||
"Create an email template by pasting your custom-coded template", | ||
icon: CodeIcon, | ||
link: "email/generate-with-html", | ||
}, | ||
{ | ||
title: "Edit in-built Template", | ||
description: | ||
"Create an email template by choosing from our custom template library", | ||
icon: FileIcon, | ||
link: "generate-with-html", | ||
}, | ||
]; | ||
|
||
describe("newTemplate component", () => { | ||
it("renders admin page cards correctly", () => { | ||
expect.assertions(6); | ||
for (const item of options) { | ||
render(<Options data={item} />); | ||
expect(screen.getByText(item.title)).toBeInTheDocument(); | ||
expect(screen.getByText(item.description)).toBeInTheDocument(); | ||
expect(screen.getAllByRole("option-icon")).toBeTruthy(); | ||
} | ||
}); | ||
|
||
it("renders page header", () => { | ||
expect.assertions(2); | ||
render( | ||
<PageHeader | ||
title="Create a New Template" | ||
description="Choose an option below to begin crafting your email design." | ||
/>, | ||
); | ||
expect.assertions(2); | ||
expect(screen.getByText("Create a New Template")).toBeInTheDocument(); | ||
expect( | ||
screen.getByText( | ||
"Choose an option below to begin crafting your email design.", | ||
), | ||
).toBeInTheDocument(); | ||
}); | ||
|
||
it("renders card with links", () => { | ||
expect.assertions(2); | ||
render(<NewTemplate />); | ||
expect(screen.getAllByRole("link")[0]).toHaveAttribute( | ||
"href", | ||
"email/generate-with-html", | ||
); | ||
expect(screen.getAllByRole("link")[1]).toHaveAttribute( | ||
"href", | ||
"generate-with-html", | ||
); | ||
}); | ||
}); |
Oops, something went wrong.