Skip to content

Commit

Permalink
feat: created super admin navbar
Browse files Browse the repository at this point in the history
  • Loading branch information
Vicdiamond committed Jul 22, 2024
2 parents 0eae20a + 52d4b9b commit a35e2e7
Show file tree
Hide file tree
Showing 109 changed files with 4,862 additions and 98 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
node_modules
/.react-email

/.cache
/build
.env

*.DS_Store
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
"source.fixAll.eslint": "always"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "vscode.typescript-language-features"
},
}
Binary file renamed app/.DS_Store → app/components/.DS_Store
Binary file not shown.
125 changes: 125 additions & 0 deletions app/components/BreadCrumbs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { Slot } from "@radix-ui/react-slot";
import { ChevronRight, MoreHorizontal } from "lucide-react";
import {
forwardRef,
type ComponentProps,
type ComponentPropsWithoutRef,
type ReactNode,
} from "react";

import { cn } from "~/lib/utils/cn";

const Breadcrumb = forwardRef<
HTMLElement,
ComponentPropsWithoutRef<"nav"> & {
separator?: ReactNode;
}
>(({ ...properties }, reference) => (
<nav ref={reference} aria-label="breadcrumb" {...properties} />
));
Breadcrumb.displayName = "Breadcrumb";

const BreadcrumbList = forwardRef<
HTMLOListElement,
ComponentPropsWithoutRef<"ol">
>(({ className, ...properties }, reference) => (
<ol
ref={reference}
className={cn(
"flex flex-wrap items-center gap-1.5 break-words text-xs text-foreground sm:gap-3",
className,
)}
{...properties}
/>
));
BreadcrumbList.displayName = "BreadcrumbList";

const BreadcrumbItem = forwardRef<
HTMLLIElement,
ComponentPropsWithoutRef<"li">
>(({ className, ...properties }, reference) => (
<li
ref={reference}
className={cn("inline-flex items-center gap-1.5", className)}
{...properties}
/>
));
BreadcrumbItem.displayName = "BreadcrumbItem";

const BreadcrumbLink = forwardRef<
HTMLAnchorElement,
ComponentPropsWithoutRef<"a"> & {
asChild?: boolean;
}
>(({ asChild, className, ...properties }, reference) => {
const Comp = asChild ? Slot : "a";

return (
<Comp
ref={reference}
className={cn(
"text-breadcrumb-foreground hover:text-neutral-dark-2 capitalize transition-colors",
className,
)}
{...properties}
/>
);
});
BreadcrumbLink.displayName = "BreadcrumbLink";

const BreadcrumbPage = forwardRef<
HTMLSpanElement,
ComponentPropsWithoutRef<"span">
>(({ className, ...properties }, reference) => (
<span
ref={reference}
role="link"
aria-disabled="true"
aria-current="page"
className={cn("text-breadcrumb-page/50 font-normal capitalize", className)}
{...properties}
/>
));
BreadcrumbPage.displayName = "BreadcrumbPage";

const BreadcrumbSeparator = ({
children,
className,
...properties
}: ComponentProps<"li">) => (
<li
role="presentation"
aria-hidden="true"
className={cn("text-breadcrumb-page [&>svg]:size-3.5", className)}
{...properties}
>
{children ?? <ChevronRight />}
</li>
);
BreadcrumbSeparator.displayName = "BreadcrumbSeparator";

const BreadcrumbEllipsis = ({
className,
...properties
}: ComponentProps<"span">) => (
<span
role="presentation"
aria-hidden="true"
className={cn("flex h-9 w-9 items-center justify-center", className)}
{...properties}
>
<MoreHorizontal className="h-4 w-4" />
<span className="sr-only">More</span>
</span>
);
BreadcrumbEllipsis.displayName = "BreadcrumbElipssis";

export {
Breadcrumb,
BreadcrumbList,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbPage,
BreadcrumbSeparator,
BreadcrumbEllipsis,
};
106 changes: 106 additions & 0 deletions app/components/CreateRoleFormModal/CreateRoleForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Form } from "@remix-run/react";
import { FC, useState } from "react";

import CreateRoleModal from "./CreateRoleModal";

interface CreateRoleFormProperties {
isOpen: boolean;
onClose: () => void;
}

const CreateRoleForm: FC<CreateRoleFormProperties> = ({ isOpen, onClose }) => {
const [roleName, setRoleName] = useState("");
const [roleDescription, setRoleDescription] = useState("");

const handleSubmit = (event: React.FormEvent) => {
event.preventDefault();

onClose();
};

return (
<CreateRoleModal isOpen={isOpen}>
<div className="p-6">
<div className="mb-4 flex items-center justify-between">
<h2 className="text-xl font-semibold">Create Role</h2>
<button
onClick={onClose}
className="text-gray-500 hover:text-gray-700"
>
<svg
className="h-6 w-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
<p className="mb-4 text-sm text-gray-600">
Define customized responsibilities for collaborative success.
</p>
<Form method="post" onSubmit={handleSubmit}>
<div className="mb-4">
<label
htmlFor="roleName"
className="mb-1 block text-sm font-bold text-[#0A0A0A]"
>
Name of role
</label>
<input
type="text"
id="roleName"
name="roleName"
placeholder="e.g: IT Staff"
value={roleName}
onChange={(event) => setRoleName(event.target.value)}
className="w-[50%] rounded-md border border-border p-2 text-sm font-normal text-[#525252]"
required
/>
</div>
<div className="mb-6">
<label
htmlFor="roleDescription"
className="mb-1 block border-border text-sm font-bold text-[#0A0A0A] outline-border"
>
Role description
</label>
<textarea
id="roleDescription"
name="roleDescription"
placeholder="Describe role"
value={roleDescription}
onChange={(event) => setRoleDescription(event.target.value)}
className="h-24 w-full resize-none rounded-md border border-gray-300 p-2 text-sm font-normal text-[#525252]"
required
/>
</div>
<div className="flex justify-end space-x-2">
<button
type="button"
onClick={onClose}
className="rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50"
>
Cancel
</button>
<button
type="submit"
className="rounded-md bg-orange-500 px-4 py-2 text-sm font-medium text-white hover:bg-orange-600"
>
Create Role
</button>
</div>
</Form>
</div>
</CreateRoleModal>
);
};

export default CreateRoleForm;
23 changes: 23 additions & 0 deletions app/components/CreateRoleFormModal/CreateRoleModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FC, ReactNode } from "react";

interface CreateRoleModalProperties {
isOpen: boolean;
children: ReactNode;
}

const CreateRoleModal: FC<CreateRoleModalProperties> = ({
isOpen,
children,
}) => {
if (!isOpen) return;

return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
<div className="mx-4 w-full max-w-md rounded-lg bg-white shadow-lg">
{children}
</div>
</div>
);
};

export default CreateRoleModal;
73 changes: 73 additions & 0 deletions app/components/DetailsForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { zodResolver } from "@hookform/resolvers/zod";
import { Form } from "@remix-run/react";
import { useForm } from "react-hook-form";
import { z, ZodType } from "zod";

import { Button } from "./ui/button";
import { Input } from "./ui/input";

type StateProperties = {
setShowSecondForm: React.Dispatch<React.SetStateAction<boolean>>;
};

const DetailsForm = (properties: StateProperties) => {
const setShowSecondForm = properties.setShowSecondForm;
type FormData = {
country: string;
fullname: string;
};

const schema: ZodType<FormData> = z.object({
country: z.string().min(2).max(30),
fullname: z.string().min(5).max(30),
});

const { register, handleSubmit } = useForm<FormData>({
resolver: zodResolver(schema),
});

const submitData = (data: FormData) => {
setShowSecondForm(true);
console.log(data);
};

return (
<div>
<Form onSubmit={handleSubmit(submitData)}>
<div className="mb-4">
<label htmlFor="country" className="mb-1 block">
Country
</label>
<Input
type="text"
placeholder="Nigeria"
className="focus:ring-none ring-inset-0 h-[40px] w-full rounded-md border border-gray-400"
{...register("country")}
/>
</div>
<div className="mb-4">
<label htmlFor="fullname" className="mb-1 block">
Full Name
</label>
<Input
type="text"
placeholder="John Smith"
className="h-[40px] w-full rounded-md border border-gray-400"
{...register("fullname")}
/>
</div>
<div className="mb-4 flex items-center gap-2">
<Input type="radio" name="companyStatus" id="" className="h-4 w-5" />
<label htmlFor="companyStatus">Are you a company?</label>
</div>
<div>
<Button className="m-auto h-[40px] w-full" type="submit">
Continue
</Button>
</div>
</Form>
</div>
);
};

export default DetailsForm;
42 changes: 42 additions & 0 deletions app/components/InvoiceEmail/DetailTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Column, Heading, Row, Section, Text } from "@react-email/components";

interface Detail {
id: number;
label: string;
value: string;
}

interface DetailTableProperties {
title: string;
text: string;
details: Detail[];
}

const DetailTable = ({ title, text, details }: DetailTableProperties) => {
return (
<Section className="my-6" style={{ borderTop: "1px solid #CBD5E1" }}>
<Heading className="my-4 font-semibold">{title}</Heading>
{text && <Text className="-mt-4">{text}</Text>}

<div
className="rounded-lg p-6 py-2"
style={{ backgroundColor: "#F6F8FB" }}
>
{details.map((detail) => (
<Row className="border-b last:border-none" key={detail.id}>
<div className="align-center flex justify-between">
<Column className="py-2 text-sm text-[#434343]">
{detail.label}
</Column>
<Column className="py-2 text-sm font-semibold text-[#0A0A0A]">
{detail.value}
</Column>
</div>
</Row>
))}
</div>
</Section>
);
};

export default DetailTable;
Loading

0 comments on commit a35e2e7

Please sign in to comment.