refactor[signUpPage]: refactor sign up page to use radix ui form modal

This commit is contained in:
igorrCarvalho 2023-08-10 02:26:06 -03:00
commit 69ec2681bd
15 changed files with 461 additions and 396 deletions

View file

@ -46,8 +46,8 @@ export default function App() {
}> }>
>([]); >([]);
const isLoginPage = location.pathname.includes('login'); const isLoginPage = location.pathname.includes("login");
const isAdminPage = location.pathname.includes('admin'); const isAdminPage = location.pathname.includes("admin");
// Use effect hook to update alertsList when a new alert is added // Use effect hook to update alertsList when a new alert is added
useEffect(() => { useEffect(() => {
@ -123,7 +123,6 @@ export default function App() {
prevAlertsList.filter((alert) => alert.id !== id) prevAlertsList.filter((alert) => alert.id !== id)
); );
}; };
return ( return (
//need parent component with width and height //need parent component with width and height
@ -137,10 +136,7 @@ export default function App() {
}} }}
FallbackComponent={CrashErrorComponent} FallbackComponent={CrashErrorComponent}
> >
{ {!isLoginPage && <Header />}
!isLoginPage
&&
<Header />}
<Router /> <Router />
</ErrorBoundary> </ErrorBoundary>
<div></div> <div></div>

View file

@ -7,5 +7,11 @@ export default function IconComponent({
iconColor, iconColor,
}: IconComponentProps): JSX.Element { }: IconComponentProps): JSX.Element {
const TargetIcon = nodeIconsLucide[name] ?? nodeIconsLucide["unknown"]; const TargetIcon = nodeIconsLucide[name] ?? nodeIconsLucide["unknown"];
return <TargetIcon strokeWidth={1.5} className={className} style={{ color: iconColor }} />; return (
<TargetIcon
strokeWidth={1.5}
className={className}
style={{ color: iconColor }}
/>
);
} }

View file

@ -35,7 +35,7 @@ export default function Header() {
<span className="ml-4 text-2xl">⛓️</span> <span className="ml-4 text-2xl">⛓️</span>
</Link> </Link>
<Button variant="outline" className=""> <Button variant="outline" className="">
Sign out Sign out
</Button> </Button>
{flows.findIndex((f) => tabId === f.id) !== -1 && tabId !== "" && ( {flows.findIndex((f) => tabId === f.id) !== -1 && tabId !== "" && (
<MenuBar flows={flows} tabId={tabId} /> <MenuBar flows={flows} tabId={tabId} />

View file

@ -10,90 +10,92 @@ export default function InputComponent({
password, password,
editNode = false, editNode = false,
placeholder = "Type something...", placeholder = "Type something...",
className,
}: InputComponentType) { }: InputComponentType) {
const [pwdVisible, setPwdVisible] = useState(false); const [pwdVisible, setPwdVisible] = useState(false);
// Clear component state // Clear component state
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
onChange(""); onChange("");
} }
}, [disabled, onChange]); }, [disabled, onChange]);
return ( return (
<div className="relative w-full"> <div className="relative w-full">
<Input <Input
value={value} value={value}
disabled={disabled} disabled={disabled}
className={classNames( className={classNames(
password && !pwdVisible && value !== "" ? " text-clip password " : "", password && !pwdVisible && value !== "" ? " text-clip password " : "",
editNode ? " input-edit-node " : "", editNode ? " input-edit-node " : "",
password && editNode ? "pr-8" : "", password && editNode ? "pr-8" : "",
password && !editNode ? "pr-10" : "" password && !editNode ? "pr-10" : "",
)} className
placeholder={password && editNode ? "Key" : placeholder} )}
onChange={(e) => { placeholder={password && editNode ? "Key" : placeholder}
onChange(e.target.value); onChange={(e) => {
}} onChange(e.target.value);
/> }}
{password && ( />
<button {password && (
className={classNames( <button
editNode className={classNames(
? "input-component-true-button" editNode
: "input-component-false-button" ? "input-component-true-button"
)} : "input-component-false-button"
onClick={() => { )}
setPwdVisible(!pwdVisible); onClick={() => {
}} setPwdVisible(!pwdVisible);
> }}
{password && >
(pwdVisible ? ( {password &&
<svg (pwdVisible ? (
xmlns="http://www.w3.org/2000/svg" <svg
fill="none" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" fill="none"
strokeWidth={1.5} viewBox="0 0 24 24"
stroke="currentColor" strokeWidth={1.5}
className={classNames( stroke="currentColor"
editNode className={classNames(
? "input-component-true-svg" editNode
: "input-component-false-svg" ? "input-component-true-svg"
)} : "input-component-false-svg"
> )}
<path >
strokeLinecap="round" <path
strokeLinejoin="round" strokeLinecap="round"
d="M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88" strokeLinejoin="round"
/> d="M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"
</svg> />
) : ( </svg>
<svg ) : (
xmlns="http://www.w3.org/2000/svg" <svg
fill="none" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" fill="none"
strokeWidth={1.5} viewBox="0 0 24 24"
stroke="currentColor" strokeWidth={1.5}
className={classNames( stroke="currentColor"
editNode className={classNames(
? "input-component-true-svg" editNode
: "input-component-false-svg" ? "input-component-true-svg"
)} : "input-component-false-svg"
> )}
<path >
strokeLinecap="round" <path
strokeLinejoin="round" strokeLinecap="round"
d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z" strokeLinejoin="round"
/> d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"
<path />
strokeLinecap="round" <path
strokeLinejoin="round" strokeLinecap="round"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" strokeLinejoin="round"
/> d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
</svg> />
))} </svg>
</button> ))}
)} </button>
</div> )}
</div>
); );
} }

View file

@ -27,4 +27,4 @@ const PopoverContent = React.forwardRef<
)); ));
PopoverContent.displayName = PopoverPrimitive.Content.displayName; PopoverContent.displayName = PopoverPrimitive.Content.displayName;
export { Popover, PopoverTrigger, PopoverContent }; export { Popover, PopoverContent, PopoverTrigger };

View file

@ -1,15 +1,15 @@
"use client" "use client";
import * as React from "react" import * as SelectPrimitive from "@radix-ui/react-select";
import * as SelectPrimitive from "@radix-ui/react-select" import { Check, ChevronDown } from "lucide-react";
import { Check, ChevronDown } from "lucide-react" import * as React from "react";
import { cn } from "../../utils/utils" import { cn } from "../../utils/utils";
const Select = SelectPrimitive.Root const Select = SelectPrimitive.Root;
const SelectGroup = SelectPrimitive.Group const SelectGroup = SelectPrimitive.Group;
const SelectValue = SelectPrimitive.Value const SelectValue = SelectPrimitive.Value;
const SelectTrigger = React.forwardRef< const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>, React.ElementRef<typeof SelectPrimitive.Trigger>,
@ -28,8 +28,8 @@ const SelectTrigger = React.forwardRef<
<ChevronDown className="h-4 w-4 opacity-50" /> <ChevronDown className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon> </SelectPrimitive.Icon>
</SelectPrimitive.Trigger> </SelectPrimitive.Trigger>
)) ));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
const SelectContent = React.forwardRef< const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>, React.ElementRef<typeof SelectPrimitive.Content>,
@ -58,8 +58,8 @@ const SelectContent = React.forwardRef<
</SelectPrimitive.Viewport> </SelectPrimitive.Viewport>
</SelectPrimitive.Content> </SelectPrimitive.Content>
</SelectPrimitive.Portal> </SelectPrimitive.Portal>
)) ));
SelectContent.displayName = SelectPrimitive.Content.displayName SelectContent.displayName = SelectPrimitive.Content.displayName;
const SelectLabel = React.forwardRef< const SelectLabel = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Label>, React.ElementRef<typeof SelectPrimitive.Label>,
@ -70,8 +70,8 @@ const SelectLabel = React.forwardRef<
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)} className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
{...props} {...props}
/> />
)) ));
SelectLabel.displayName = SelectPrimitive.Label.displayName SelectLabel.displayName = SelectPrimitive.Label.displayName;
const SelectItem = React.forwardRef< const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>, React.ElementRef<typeof SelectPrimitive.Item>,
@ -93,8 +93,8 @@ const SelectItem = React.forwardRef<
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText> <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item> </SelectPrimitive.Item>
)) ));
SelectItem.displayName = SelectPrimitive.Item.displayName SelectItem.displayName = SelectPrimitive.Item.displayName;
const SelectSeparator = React.forwardRef< const SelectSeparator = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Separator>, React.ElementRef<typeof SelectPrimitive.Separator>,
@ -105,16 +105,16 @@ const SelectSeparator = React.forwardRef<
className={cn("-mx-1 my-1 h-px bg-muted", className)} className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props} {...props}
/> />
)) ));
SelectSeparator.displayName = SelectPrimitive.Separator.displayName SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
export { export {
Select, Select,
SelectGroup,
SelectValue,
SelectTrigger,
SelectContent, SelectContent,
SelectLabel, SelectGroup,
SelectItem, SelectItem,
SelectLabel,
SelectSeparator, SelectSeparator,
} SelectTrigger,
SelectValue,
};

View file

@ -510,7 +510,7 @@ export const URL_EXCLUDED_FROM_ERROR_RETRIES = [
]; ];
export const CONTROL_INPUT_STATE = { export const CONTROL_INPUT_STATE = {
password: '', password: "",
cnfPassword: '', cnfPassword: "",
username: '', username: "",
}; };

View file

@ -1,6 +1,5 @@
import axios, { AxiosError, AxiosInstance } from "axios"; import axios, { AxiosError, AxiosInstance } from "axios";
import { useContext, useEffect, useRef } from "react"; import { useContext, useEffect, useRef } from "react";
import { URL_EXCLUDED_FROM_ERROR_RETRIES } from "../../constants/constants";
import { alertContext } from "../../contexts/alertContext"; import { alertContext } from "../../contexts/alertContext";
// Create a new Axios instance // Create a new Axios instance
@ -20,7 +19,6 @@ function ApiInterceptor() {
// return Promise.reject(error); // return Promise.reject(error);
// } // }
// let retryCount = 0; // let retryCount = 0;
// while (retryCount < 4) { // while (retryCount < 4) {
// await sleep(5000); // Sleep for 5 seconds // await sleep(5000); // Sleep for 5 seconds
// retryCount++; // retryCount++;

View file

@ -47,7 +47,15 @@ interface BaseModalProps {
open?: boolean; open?: boolean;
setOpen?: (open: boolean) => void; setOpen?: (open: boolean) => void;
disable?: boolean; disable?: boolean;
size?: "x-small" | "smaller" | "small" | "medium" | "large" | "large-h-full" | "small-h-full" | "medium-h-full"; size?:
| "x-small"
| "smaller"
| "small"
| "medium"
| "large"
| "large-h-full"
| "small-h-full"
| "medium-h-full";
} }
function BaseModal({ function BaseModal({
open, open,
@ -85,16 +93,16 @@ function BaseModal({
minWidth = "min-w-[40vw]"; minWidth = "min-w-[40vw]";
height = "h-[40vh]"; height = "h-[40vh]";
break; break;
case "small-h-full": case "small-h-full":
minWidth = "min-w-[40vw]"; minWidth = "min-w-[40vw]";
break; break;
case "medium": case "medium":
minWidth = "min-w-[60vw]"; minWidth = "min-w-[60vw]";
height = "h-[60vh]"; height = "h-[60vh]";
break; break;
case "medium-h-full": case "medium-h-full":
minWidth = "min-w-[60vw]"; minWidth = "min-w-[60vw]";
break; break;
case "large": case "large":
minWidth = "min-w-[80vw]"; minWidth = "min-w-[80vw]";
height = "h-[80vh]"; height = "h-[80vh]";
@ -118,7 +126,7 @@ function BaseModal({
{triggerChild} {triggerChild}
</DialogTrigger> </DialogTrigger>
<DialogContent className={minWidth}> <DialogContent className={minWidth}>
<div className="word-break-break-word truncate-doubleline"> <div className="truncate-doubleline word-break-break-word">
{headerChild} {headerChild}
</div> </div>
<div className={`mt-2 flex flex-col ${height} w-full `}> <div className={`mt-2 flex flex-col ${height} w-full `}>

View file

@ -1,29 +1,28 @@
import { FaApple, FaGithub } from "react-icons/fa"; import { useNavigate } from "react-router-dom";
import { Button } from "../../../components/ui/button"; import { Button } from "../../../components/ui/button";
import { Input } from "../../../components/ui/input"; import { Input } from "../../../components/ui/input";
import { GoogleIcon } from "../../../icons/Google";
import { useNavigate } from "react-router-dom";
export default function LoginAdminPage() { export default function LoginAdminPage() {
const navigate = useNavigate(); const navigate = useNavigate();
function loginAdmin() { function loginAdmin() {
navigate("/admin/"); navigate("/admin/");
} }
return ( return (
<div className="flex h-full w-full flex-col items-center justify-center bg-muted"> <div className="flex h-full w-full flex-col items-center justify-center bg-muted">
<div className="flex w-72 flex-col items-center justify-center gap-2"> <div className="flex w-72 flex-col items-center justify-center gap-2">
<span className="mb-4 text-5xl">⛓️</span> <span className="mb-4 text-5xl">⛓️</span>
<span className="mb-6 text-2xl font-semibold text-primary"> <span className="mb-6 text-2xl font-semibold text-primary">Admin</span>
Admin
</span>
<Input className="bg-background" placeholder="Email address" /> <Input className="bg-background" placeholder="Email address" />
<Input className="bg-background" placeholder="Password" /> <Input className="bg-background" placeholder="Password" />
<Button <Button
onClick={() => {loginAdmin()}} onClick={() => {
variant="default" className="w-full"> loginAdmin();
}}
variant="default"
className="w-full"
>
Login Login
</Button> </Button>
</div> </div>

View file

@ -1,8 +1,9 @@
import _ from "lodash"; import _ from "lodash";
import { Pencil, Trash2, X } from "lucide-react"; import { X } from "lucide-react";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import PaginatorComponent from "../../components/PaginatorComponent"; import PaginatorComponent from "../../components/PaginatorComponent";
import ShadTooltip from "../../components/ShadTooltipComponent"; import ShadTooltip from "../../components/ShadTooltipComponent";
import IconComponent from "../../components/genericIconComponent";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
import { Input } from "../../components/ui/input"; import { Input } from "../../components/ui/input";
import { import {
@ -15,7 +16,6 @@ import {
} from "../../components/ui/table"; } from "../../components/ui/table";
import ConfirmationModal from "../../modals/ConfirmationModal"; import ConfirmationModal from "../../modals/ConfirmationModal";
import UserManagementModal from "../../modals/UserManagementModal"; import UserManagementModal from "../../modals/UserManagementModal";
import IconComponent from "../../components/genericIconComponent";
export default function AdminPage() { export default function AdminPage() {
const [inputValue, setInputValue] = useState(""); const [inputValue, setInputValue] = useState("");
@ -249,154 +249,153 @@ export default function AdminPage() {
return ( return (
<> <>
<div className="main-page-panel"> <div className="main-page-panel">
<div className="h-full m-auto flex flex-row justify-center"> <div className="m-auto flex h-full flex-row justify-center">
<div className="basis-5/6"> <div className="basis-5/6">
<div className="m-auto h-full flex-col space-y-8 p-8 flex "> <div className="m-auto flex h-full flex-col space-y-8 p-8 ">
<div className="flex items-center justify-between space-y-2"> <div className="flex items-center justify-between space-y-2">
<div> <div>
<h2 className="text-2xl font-bold tracking-tight"> <h2 className="text-2xl font-bold tracking-tight">
Welcome back! Welcome back!
</h2> </h2>
<p className="text-muted-foreground"> <p className="text-muted-foreground">
Here&apos;s a list of all users! Here&apos;s a list of all users!
</p> </p>
</div>
<div className="flex items-center space-x-2"></div>
</div> </div>
<div className="flex items-center space-x-2"></div>
</div>
{userList.current.length === 0 && ( {userList.current.length === 0 && (
<> <>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h2>There's no users left :)</h2> <h2>There's no users left :)</h2>
</div> </div>
</> </>
)} )}
{userList.current.length > 0 && ( {userList.current.length > 0 && (
<> <>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex flex-1 items-center space-x-2"> <div className="flex flex-1 items-center space-x-2">
<Input <Input
value={inputValue} value={inputValue}
placeholder="Filter users..." placeholder="Filter users..."
className="h-8 w-[150px] lg:w-[250px]" className="h-8 w-[150px] lg:w-[250px]"
onChange={(e) => handleFilterUsers(e.target.value)} onChange={(e) => handleFilterUsers(e.target.value)}
/> />
{inputValue.length > 0 && ( {inputValue.length > 0 && (
<Button <Button
onClick={() => { onClick={() => {
resetFilter(); resetFilter();
setInputValue(""); setInputValue("");
}}
variant="ghost"
className="h-8 px-2 lg:px-3"
>
Reset
<X className="ml-2 h-4 w-4" />
</Button>
)}
</div>
<div>
<UserManagementModal
title="New User"
titleHeader={"Add a new user"}
cancelText="Cancel"
confirmationText="Save"
icon={"UserPlus2"}
onConfirm={(index, user) => {
handleNewUser(user);
}} }}
variant="ghost"
className="h-8 px-2 lg:px-3"
> >
Reset <Button>New User</Button>
<X className="ml-2 h-4 w-4" /> </UserManagementModal>
</Button> </div>
)}
</div> </div>
<div> <div
<UserManagementModal className="overflow-scroll overflow-x-hidden rounded-md border-2 bg-muted
title="New User"
titleHeader={"Add a new user"}
cancelText="Cancel"
confirmationText="Save"
icon={"UserPlus2"}
onConfirm={(index, user) => {
handleNewUser(user);
}}
>
<Button>New User</Button>
</UserManagementModal>
</div>
</div>
<div
className="overflow-scroll overflow-x-hidden rounded-md border-2 bg-muted
custom-scroll" custom-scroll"
> >
<Table className="table-fixed bg-muted outline-1 "> <Table className="table-fixed bg-muted outline-1 ">
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead className="h-10">User</TableHead> <TableHead className="h-10">User</TableHead>
<TableHead className="h-10">Password</TableHead> <TableHead className="h-10">Password</TableHead>
<TableHead className="h-10 w-[100px] text-right"></TableHead> <TableHead className="h-10 w-[100px] text-right"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{filterUserList.map((user, index) => (
<TableRow key={user.user}>
<TableCell className="truncate py-2 font-medium">
{user.user}
</TableCell>
<TableCell className="truncate py-2">
{user.password}
</TableCell>
<TableCell className="flex w-[100px] py-2 text-right">
<div className="flex">
<UserManagementModal
title="Edit"
titleHeader={`${user.user}`}
cancelText="Cancel"
confirmationText="Edit"
icon={"UserPlus2"}
data={user}
index={index}
onConfirm={(index, user) => {
handleEditUser(index, user);
}}
>
<ShadTooltip content="Edit" side="top">
<IconComponent name="Pencil"
className="h-4 w-4 cursor-pointer"
/>
</ShadTooltip>
</UserManagementModal>
<ConfirmationModal
title="Delete"
titleHeader="Delete User"
modalContentTitle="Attention!"
modalContent="Are you sure you want to delete this user? This action cannot be undone."
cancelText="Cancel"
confirmationText="Delete"
icon={"UserMinus2"}
data={user}
index={index}
onConfirm={(index, user) => {
handleDeleteUser(index);
}}
>
<ShadTooltip content="Delete" side="top">
<IconComponent name="Trash2"
className="ml-2 h-4 w-4 cursor-pointer"
/>
</ShadTooltip>
</ConfirmationModal>
</div>
</TableCell>
</TableRow> </TableRow>
))} </TableHeader>
</TableBody> <TableBody>
</Table> {filterUserList.map((user, index) => (
</div> <TableRow key={user.user}>
<PaginatorComponent <TableCell className="truncate py-2 font-medium">
pageIndex={index} {user.user}
pageSize={size} </TableCell>
totalRowsCount={filterUserList.length} <TableCell className="truncate py-2">
paginate={(pageIndex, pageSize) => { {user.password}
handleChangePagination(pageSize, pageIndex); </TableCell>
}} <TableCell className="flex w-[100px] py-2 text-right">
></PaginatorComponent> <div className="flex">
</> <UserManagementModal
)} title="Edit"
titleHeader={`${user.user}`}
cancelText="Cancel"
confirmationText="Edit"
icon={"UserPlus2"}
data={user}
index={index}
onConfirm={(index, user) => {
handleEditUser(index, user);
}}
>
<ShadTooltip content="Edit" side="top">
<IconComponent
name="Pencil"
className="h-4 w-4 cursor-pointer"
/>
</ShadTooltip>
</UserManagementModal>
<ConfirmationModal
title="Delete"
titleHeader="Delete User"
modalContentTitle="Attention!"
modalContent="Are you sure you want to delete this user? This action cannot be undone."
cancelText="Cancel"
confirmationText="Delete"
icon={"UserMinus2"}
data={user}
index={index}
onConfirm={(index, user) => {
handleDeleteUser(index);
}}
>
<ShadTooltip content="Delete" side="top">
<IconComponent
name="Trash2"
className="ml-2 h-4 w-4 cursor-pointer"
/>
</ShadTooltip>
</ConfirmationModal>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
<PaginatorComponent
pageIndex={index}
pageSize={size}
totalRowsCount={filterUserList.length}
paginate={(pageIndex, pageSize) => {
handleChangePagination(pageSize, pageIndex);
}}
></PaginatorComponent>
</>
)}
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
</> </>
); );
} }

View file

@ -1,104 +1,157 @@
import _ from "lodash"; import * as Form from "@radix-ui/react-form";
import { useState } from "react";
import { FaApple, FaGithub } from "react-icons/fa"; import { FaApple, FaGithub } from "react-icons/fa";
import InputComponent from "../../components/inputComponent";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
import { Input } from "../../components/ui/input"; import { Input } from "../../components/ui/input";
import { GoogleIcon } from "../../icons/Google";
import { useContext, useState } from "react";
import { CONTROL_INPUT_STATE } from "../../constants/constants"; import { CONTROL_INPUT_STATE } from "../../constants/constants";
import { GoogleIcon } from "../../icons/Google";
import { inputHandlerEventType, inputStateType } from "../../types/components"; import { inputHandlerEventType, inputStateType } from "../../types/components";
import { alertContext } from "../../contexts/alertContext";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import InputComponent from "../../components/inputComponent"; import IconComponent from "../../components/genericIconComponent";
export default function SignUp(): JSX.Element { export default function SignUp(): JSX.Element {
const [inputState, setInputState] = useState<inputStateType>(CONTROL_INPUT_STATE); const [inputState, setInputState] =
useState<inputStateType>(CONTROL_INPUT_STATE);
const {
setErrorData,
errorOpen,
} = useContext(alertContext);
const { password, cnfPassword, username } = inputState; const { password, cnfPassword, username } = inputState;
function handleInput({ target: { name, value } }: inputHandlerEventType): void { function handleInput({
setInputState((prev) => ({ ...prev, [name]: value })); target: { name, value },
}; }: inputHandlerEventType): void {
setInputState((prev) => ({ ...prev, [name]: value }));
function handleSignUpPass() { }
if (password !== cnfPassword) {
const errorDat = {
title: "Passwords are not equal",
};
return setErrorData(errorDat);
}
let err = [];
Object.keys(inputState)
.forEach((key) => {
if (inputState[key] === '') {
err.push(key);
}
});
setErrorData({
title: "Mandatory fields are empty",
list: err,
});
}
return ( return (
<div className="flex h-full w-full flex-col items-center justify-center bg-muted"> <Form.Root
<div className="flex w-72 flex-col items-center justify-center gap-2"> onSubmit={(event) => {
<span className="mb-4 text-5xl">⛓️</span> if (password !== cnfPassword) {
<span className="mb-6 text-2xl font-semibold text-primary"> event.preventDefault();
Sign up to LangFlow return;
</span> }
<div className="flex w-full items-center justify-center gap-2">
<Button variant="primary" className="w-full py-6"> const data = Object.fromEntries(new FormData(event.currentTarget));
<FaApple className="h-6 w-6" /> event.preventDefault();
</Button> }}
<Button variant="primary" className="w-full py-6"> className="w-full h-full"
<FaGithub className="h-6 w-6" /> >
</Button> <div className="flex h-full w-full flex-col items-center justify-center bg-muted">
<Button variant="primary" className="w-full py-6"> <div className="flex w-72 flex-col items-center justify-center gap-2">
<div className="h-6 w-6"> <span className="mb-4 text-5xl">⛓️</span>
<GoogleIcon /> <span className="mb-6 text-2xl font-semibold text-primary">
</div> Sign up to LangFlow
</Button> </span>
</div> <div className="flex w-full items-center justify-center gap-2">
<span className="text-sm text-muted-foreground">or</span> <Button variant="primary" className="w-full py-6">
<Input <IconComponent
className="bg-background" name="FaApple"
placeholder="Username" className="h-6 w-6"
name="username" />
value={username} </Button>
onChange={handleInput} <Button variant="primary" className="w-full py-6">
type="text" <IconComponent
/> name="FaGithub"
<InputComponent className="h-6 w-6"
value={password} />
onChange={(value) => handleInput({ target: { name: 'password', value } })} </Button>
password={true} <Button variant="primary" className="w-full py-6">
placeholder="Password" <IconComponent
/> name="GoogleSearchRun"
<InputComponent className="h-6 w-6"
value={cnfPassword} />
onChange={(value) => handleInput({ target: { name: 'cnfPassword', value } })} </Button>
password={true} </div>
placeholder="Confirm your password" <span className="text-sm text-muted-foreground">or</span>
/> <div className="w-full mb-3">
<Button <Form.Field name="username">
variant="default" <Form.Label className="data-[invalid]:label-invalid">
className="w-full" Username <span className="font-medium text-destructive">*</span>
onClick={() => { </Form.Label>
handleSignUpPass();
}} <Form.Control asChild>
> <Input
Sign up onChange={({ target: { value } }) => {
</Button> handleInput({ target: { name: "username", value } });
<Link to="/login" className="mt-6 w-full"> }}
<Button variant="outline" className="mt-6 w-full"> value={username}
Already have an account?&nbsp;<b>Sign in</b> className="w-full"
</Button> required
</Link> placeholder="Username"
</div> />
</div> </Form.Control>
<Form.Message match="valueMissing" className="field-invalid">
Please enter your username
</Form.Message>
</Form.Field>
</div>
<div className="w-full mb-3">
<Form.Field name="password" serverInvalid={password != cnfPassword}>
<Form.Label className="data-[invalid]:label-invalid">
Password <span className="font-medium text-destructive">*</span>
</Form.Label>
<Form.Control asChild>
<InputComponent
onChange={(value) => {
handleInput({ target: { name: "password", value } });
}}
value={password}
password={true}
placeholder="Password"
className="w-full"
/>
</Form.Control>
<Form.Message className="field-invalid" match="valueMissing">
Please enter a password
</Form.Message>
{password != cnfPassword && (
<Form.Message className="field-invalid">
Passwords do not match
</Form.Message>
)}
</Form.Field>
</div>
<div className="w-full">
<Form.Field
name="confirmpassword"
serverInvalid={password != cnfPassword}
>
<Form.Label className="data-[invalid]:label-invalid">
Confirm your password{" "}
<span className="font-medium text-destructive">*</span>
</Form.Label>
<Form.Control asChild>
<InputComponent
onChange={(value) => {
handleInput({ target: { name: "cnfPassword", value } });
}}
value={cnfPassword}
password={true}
/>
</Form.Control>
<Form.Message className="field-invalid" match="valueMissing">
Please confirm your password
</Form.Message>
</Form.Field>
</div>
<div className="w-full">
<Form.Submit asChild>
<Button className="mr-3 mt-6 w-full">Sign up</Button>
</Form.Submit>
</div>
<div className="w-full">
<Link to="/login">
<Button className="w-full" variant="outline">
Already have an account?&nbsp;<b>Sign in</b>
</Button>
</Link>
</div>
</div>
</div>
</Form.Root>
); );
} }

View file

@ -1,12 +1,12 @@
import { Route, Routes } from "react-router-dom"; import { Route, Routes } from "react-router-dom";
import AdminPage from "./pages/AdminPage";
import LoginAdminPage from "./pages/AdminPage/LoginPage";
import CommunityPage from "./pages/CommunityPage"; import CommunityPage from "./pages/CommunityPage";
import FlowPage from "./pages/FlowPage"; import FlowPage from "./pages/FlowPage";
import HomePage from "./pages/MainPage"; import HomePage from "./pages/MainPage";
import DeleteAccountPage from "./pages/deleteAccountPage"; import DeleteAccountPage from "./pages/deleteAccountPage";
import LoginPage from "./pages/loginPage"; import LoginPage from "./pages/loginPage";
import SignUp from "./pages/signUpPage"; import SignUp from "./pages/signUpPage";
import LoginAdminPage from "./pages/AdminPage/LoginPage";
import AdminPage from "./pages/AdminPage";
const Router = () => { const Router = () => {
return ( return (
@ -17,13 +17,13 @@ const Router = () => {
<Route path="" element={<FlowPage />} /> <Route path="" element={<FlowPage />} />
</Route> </Route>
<Route path="*" element={<HomePage />} /> <Route path="*" element={<HomePage />} />
<Route path="/login" element={<LoginPage />} /> <Route path="/login" element={<LoginPage />} />
<Route path="/signup" element={<SignUp/>} /> <Route path="/signup" element={<SignUp />} />
<Route path="/login/admin" element={<LoginAdminPage />} /> <Route path="/login/admin" element={<LoginAdminPage />} />
<Route path="/admin" element={<AdminPage />} /> <Route path="/admin" element={<AdminPage />} />
<Route path="/account"> <Route path="/account">
<Route path="delete" element={<DeleteAccountPage />}></Route> <Route path="delete" element={<DeleteAccountPage />}></Route>
</Route> </Route>

View file

@ -11,6 +11,7 @@ export type InputComponentType = {
onChangePass?: (value: boolean | boolean) => void; onChangePass?: (value: boolean | boolean) => void;
showPass?: boolean; showPass?: boolean;
placeholder?: string; placeholder?: string;
className?: string;
}; };
export type ToggleComponentType = { export type ToggleComponentType = {
enabled: boolean; enabled: boolean;
@ -82,13 +83,13 @@ export type DisclosureComponentType = {
children: ReactNode; children: ReactNode;
openDisc: boolean; openDisc: boolean;
button: { button: {
title: string; title: string;
Icon: any; Icon: any;
buttons?: { buttons?: {
Icon: ReactElement; Icon: ReactElement;
title: string; title: string;
onClick: (event?: React.MouseEvent) => void; onClick: (event?: React.MouseEvent) => void;
}[]; }[];
}; };
}; };
export type FloatComponentType = { export type FloatComponentType = {
@ -102,18 +103,18 @@ export type TooltipComponentType = {
children: ReactElement; children: ReactElement;
title: string | ReactElement; title: string | ReactElement;
placement?: placement?:
| "bottom-end" | "bottom-end"
| "bottom-start" | "bottom-start"
| "bottom" | "bottom"
| "left-end" | "left-end"
| "left-start" | "left-start"
| "left" | "left"
| "right-end" | "right-end"
| "right-start" | "right-start"
| "right" | "right"
| "top-end" | "top-end"
| "top-start" | "top-start"
| "top"; | "top";
}; };
export type ProgressBarType = { export type ProgressBarType = {
@ -165,7 +166,7 @@ export interface IVarHighlightType {
export type IconComponentProps = { export type IconComponentProps = {
name: string; name: string;
className: string; className?: string;
iconColor?: string; iconColor?: string;
}; };
@ -181,8 +182,8 @@ export type inputStateType = {
export type inputHandlerEventType = { export type inputHandlerEventType = {
target: { target: {
value: string; value: string;
name: string; name: string;
}; };
}; };
export type PaginatorComponentType = { export type PaginatorComponentType = {
@ -205,7 +206,7 @@ export type ConfirmationModalType = {
data: any; data: any;
index: number; index: number;
onConfirm: (index, data) => void; onConfirm: (index, data) => void;
} };
export type UserManagementType = { export type UserManagementType = {
title: string; title: string;
@ -217,4 +218,4 @@ export type UserManagementType = {
data?: any; data?: any;
index?: number; index?: number;
onConfirm: (index, data) => void; onConfirm: (index, data) => void;
} };

View file

@ -5,6 +5,8 @@ import {
ChevronDown, ChevronDown,
ChevronLeft, ChevronLeft,
ChevronRight, ChevronRight,
ChevronsLeft,
ChevronsRight,
ChevronsUpDown, ChevronsUpDown,
Circle, Circle,
Clipboard, Clipboard,
@ -44,6 +46,7 @@ import {
MoonIcon, MoonIcon,
MoreHorizontal, MoreHorizontal,
Paperclip, Paperclip,
Pencil,
Plus, Plus,
Redo, Redo,
Rocket, Rocket,
@ -66,9 +69,6 @@ import {
X, X,
XCircle, XCircle,
Zap, Zap,
Pencil,
ChevronsRight,
ChevronsLeft
} from "lucide-react"; } from "lucide-react";
import { AirbyteIcon } from "../icons/Airbyte"; import { AirbyteIcon } from "../icons/Airbyte";
import { AnthropicIcon } from "../icons/Anthropic"; import { AnthropicIcon } from "../icons/Anthropic";
@ -96,6 +96,7 @@ import SvgWikipedia from "../icons/Wikipedia/Wikipedia";
import SvgWolfram from "../icons/Wolfram/Wolfram"; import SvgWolfram from "../icons/Wolfram/Wolfram";
import { HackerNewsIcon } from "../icons/hackerNews"; import { HackerNewsIcon } from "../icons/hackerNews";
import { SupabaseIcon } from "../icons/supabase"; import { SupabaseIcon } from "../icons/supabase";
import { FaApple, FaGithub } from "react-icons/fa";
export const gradients = [ export const gradients = [
"bg-gradient-to-br from-gray-800 via-rose-700 to-violet-900", "bg-gradient-to-br from-gray-800 via-rose-700 to-violet-900",
@ -284,5 +285,7 @@ export const nodeIconsLucide = {
UserPlus2, UserPlus2,
Pencil, Pencil,
ChevronsRight, ChevronsRight,
ChevronsLeft ChevronsLeft,
FaGithub,
FaApple,
}; };