Fixed top header to more dynamic

This commit is contained in:
Laux Dev
2026-03-03 09:53:57 +08:00
parent 672e6e0a1d
commit 3eb0ee06fb
24 changed files with 260 additions and 41 deletions

View File

@@ -23,6 +23,7 @@ const Page = () => {
cancelButtonText="Cancel" cancelButtonText="Cancel"
topbarTitle="Update Agent" topbarTitle="Update Agent"
state="add" state="add"
requiredButtons={["update", "title"]}
/> />
{/* Create agent Container */} {/* Create agent Container */}
<div className={createAgentStyle.createAgentContainer}> <div className={createAgentStyle.createAgentContainer}>

View File

@@ -23,6 +23,7 @@ const Page = () => {
cancelButtonText="Cancel" cancelButtonText="Cancel"
topbarTitle="Create New Agent" topbarTitle="Create New Agent"
state="add" state="add"
requiredButtons={["title", "save"]}
/> />
{/* Create agent Container */} {/* Create agent Container */}
<div className={createAgentStyle.createAgentContainer}> <div className={createAgentStyle.createAgentContainer}>

View File

@@ -99,7 +99,11 @@ const AgentsPage = () => {
<div className={globalStyle.section}> <div className={globalStyle.section}>
<div className={globalStyle.mainContainer}> <div className={globalStyle.mainContainer}>
<div className={globalStyle.container}> <div className={globalStyle.container}>
<TopHeader buttonText="Add Agents" topbarTitle="Agents" /> <TopHeader
buttonText="Add Agents"
topbarTitle="Agents"
requiredButtons={["title", "add", "search"]}
/>
<div className={styles.tableContainer}> <div className={styles.tableContainer}>
<table className={styles.table}> <table className={styles.table}>
<thead> <thead>

View File

@@ -4,8 +4,8 @@ import AddIcon from "../../icons/add";
const PrimaryButton = (props) => { const PrimaryButton = (props) => {
return ( return (
<button className={styles.button} {...props}> <button className={styles.button} {...props}>
<AddIcon width={20} height={20} /> {props?.icon}
Add {props.text}
</button> </button>
); );
}; };

View File

@@ -1,14 +1,14 @@
.button { .button {
display: flex; display: flex;
padding: 8px 24px; padding: 7px 15px;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
gap: 8px; gap: 10px;
font-family: inter; border-radius: 6px;
border-radius: 6px; border-radius: 6px;
border: 0.5px solid #8187ff; border: 0.5px solid #8187ff;
background: rgba(83, 89, 242, 0.25); background: rgba(83, 89, 242, 0.25);
color: #fff; color: white;
font-size: 16px; font-size: 16px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;

View File

@@ -0,0 +1,33 @@
const EditIcon = ({ width = 20, height = 20, color = "white", ...props }) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
viewBox="0 0 20 20"
fill="none"
{...props}
>
<path
d="M5.83398 5.83301H5.00065C4.55862 5.83301 4.1347 6.0086 3.82214 6.32116C3.50958 6.63372 3.33398 7.05765 3.33398 7.49967V14.9997C3.33398 15.4417 3.50958 15.8656 3.82214 16.1782C4.1347 16.4907 4.55862 16.6663 5.00065 16.6663H12.5007C12.9427 16.6663 13.3666 16.4907 13.6792 16.1782C13.9917 15.8656 14.1673 15.4417 14.1673 14.9997V14.1663"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M16.9875 5.48759C17.3157 5.15938 17.5001 4.71424 17.5001 4.25009C17.5001 3.78594 17.3157 3.34079 16.9875 3.01259C16.6593 2.68438 16.2142 2.5 15.75 2.5C15.2858 2.5 14.8407 2.68438 14.5125 3.01259L7.5 10.0001V12.5001H10L16.9875 5.48759Z"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M13.334 4.16699L15.834 6.66699"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
export default EditIcon;

View File

@@ -0,0 +1,26 @@
const OutlineDownloadIcon = ({
width = 24,
height = 24,
color = "#D2D3E0",
...props
}) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
viewBox="0 0 24 24"
fill="none"
{...props}
>
<path
d="M4.33398 16.7913V18.708C4.33398 19.2163 4.53592 19.7039 4.89536 20.0633C5.25481 20.4227 5.74232 20.6247 6.25065 20.6247H17.7507C18.259 20.6247 18.7465 20.4227 19.1059 20.0633C19.4654 19.7039 19.6673 19.2163 19.6673 18.708V16.7913M7.20898 11.0413L12.0007 15.833M12.0007 15.833L16.7923 11.0413M12.0007 15.833V4.33301"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
export default OutlineDownloadIcon;

View File

@@ -0,0 +1,26 @@
const RestartIcon = ({
width = 24,
height = 24,
color = "#D2D3E0",
...props
}) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
viewBox="0 0 24 24"
fill="none"
{...props}
>
<path
d="M19.6673 11.0417C19.4329 9.35521 18.6506 7.79259 17.4408 6.59452C16.2309 5.39645 14.6608 4.62938 12.9721 4.41149C11.2834 4.1936 9.56996 4.53697 8.09564 5.3887C6.62132 6.24043 5.46793 7.55328 4.81315 9.125M4.33398 5.29167V9.125H8.16732M4.33398 12.9583C4.56835 14.6448 5.35071 16.2074 6.56054 17.4055C7.77037 18.6036 9.34055 19.3706 11.0292 19.5885C12.7179 19.8064 14.4313 19.463 15.9057 18.6113C17.38 17.7596 18.5334 16.4467 19.1882 14.875M19.6673 18.7083V14.875H15.834"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
export default RestartIcon;

View File

@@ -0,0 +1,35 @@
const UpdateIcon = ({
width = 20,
height = 20,
color = "white",
strokeWidth = 1.5,
...props
}) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
viewBox="0 0 20 20"
fill="none"
{...props}
>
<path
d="M16.25 9.2188C16.0589 7.84397 15.4211 6.57009 14.4349 5.5934C13.4486 4.61671 12.1686 3.99139 10.7919 3.81376C9.4153 3.63613 8.01845 3.91605 6.81656 4.61039C5.61467 5.30474 4.67441 6.375 4.14062 7.6563M3.75 4.5313V7.6563H6.875"
stroke={color}
strokeWidth={strokeWidth}
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M3.75 10.7812C3.94106 12.1561 4.57885 13.43 5.56513 14.4066C6.5514 15.3833 7.83144 16.0087 9.20807 16.1863C10.5847 16.3639 11.9815 16.084 13.1834 15.3897C14.3853 14.6953 15.3256 13.6251 15.8594 12.3437M16.25 15.4687V12.3437H13.125"
stroke={color}
strokeWidth={strokeWidth}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
export default UpdateIcon;

View File

@@ -13,6 +13,12 @@ import RobotIcon from "../icons/robot";
import KeyIcon from "../icons/key"; import KeyIcon from "../icons/key";
import ManageEnvIcon from "../icons/manageEnv"; import ManageEnvIcon from "../icons/manageEnv";
import Alert from "../alerts/Alert"; import Alert from "../alerts/Alert";
import DownloadIcon from "../icons/download";
import OutlineDownloadIcon from "../icons/outlineDownload";
import RestartIcon from "../icons/restart";
import PrimaryButton from "../buttons/primarybutton/PrimaryButton";
import EditIcon from "../icons/edit";
import UpdateIcon from "../icons/update";
const TopHeader = (props) => { const TopHeader = (props) => {
const [triggerDropDownMenu, setTriggerDropDownMenu] = useState(false); const [triggerDropDownMenu, setTriggerDropDownMenu] = useState(false);
@@ -28,9 +34,7 @@ const TopHeader = (props) => {
{triggerAlert && <Alert setTriggerAlert={setTriggerAlert} />} {triggerAlert && <Alert setTriggerAlert={setTriggerAlert} />}
<div className={styles.container}> <div className={styles.container}>
<div className={styles.title}> <div className={styles.title}>
{((pathName.includes("/view") && props.state === "view") || {props.requiredButtons.includes("back") && (
params.usersId ||
params.rolesId) && (
<div onClick={() => router.back()}> <div onClick={() => router.back()}>
<BackIcon /> <BackIcon />
</div> </div>
@@ -38,35 +42,39 @@ const TopHeader = (props) => {
<p>{props.topbarTitle}</p> <p>{props.topbarTitle}</p>
</div> </div>
<div className={styles.actionBar}> <div className={styles.actionBar}>
{(pathName === "/projects/view" || !props.state) && ( {props.requiredButtons.includes("search") && (
<div className={styles.searchBarContainer}> <div className={styles.searchBarContainer}>
<SearchIcon /> <SearchIcon />
</div> </div>
)} )}
{pathName === "/credentials" ? ( {props.requiredButtons.includes("env") && (
<div className={styles.mngEnvKeyButton}> <div className={styles.mngEnvKeyButton}>
<EnviromentIcon /> <EnviromentIcon />
<p>Manage Env. Key</p> <p>Manage Env. Key</p>
</div> </div>
) : (
""
)} )}
{pathName === "/projects/view" && ( {props.requiredButtons.includes("add-services") && (
<div <PrimaryButton
className={styles.button} icon={<AddIcon />}
text={props.buttonText}
onClick={() => props.trigger(!props.triggerState)} onClick={() => props.trigger(!props.triggerState)}
> />
<AddIcon />
<p>{props.buttonText}</p>
</div>
)} )}
{!props.state && ( {props.requiredButtons.includes("edit") && (
<div className={styles.button} onClick={handleNavigateToAdd}> <PrimaryButton
<AddIcon /> icon={<EditIcon />}
<p>{props.buttonText}</p> text="Edit"
</div> onClick={() => props.trigger(!props.triggerState)}
/>
)} )}
{props.state === "add" ? ( {props.requiredButtons.includes("add") && (
<PrimaryButton
icon={<AddIcon />}
text={props.buttonText}
onClick={handleNavigateToAdd}
/>
)}
{props.requiredButtons.includes("save") && (
<> <>
<div <div
className={styles.button} className={styles.button}
@@ -82,11 +90,22 @@ const TopHeader = (props) => {
<p>{props.cancelButtonText}</p> <p>{props.cancelButtonText}</p>
</div> </div>
</> </>
) : (
""
)} )}
{/* Projects 3 dots menu */} {props.requiredButtons.includes("update") && (
{pathName === "/projects/view" && ( <>
<PrimaryButton
icon={<UpdateIcon color="white" />}
text="Update"
/>
<div
className={styles.cancelButton}
onClick={() => router.back()}
>
<p>{props.cancelButtonText}</p>
</div>
</>
)}
{props?.requiredButtons?.includes("services-drop-down") && (
<div <div
className={styles.menu} className={styles.menu}
onClick={() => setTriggerDropDownMenu(!triggerDropDownMenu)} onClick={() => setTriggerDropDownMenu(!triggerDropDownMenu)}
@@ -124,6 +143,39 @@ const TopHeader = (props) => {
)} )}
</div> </div>
)} )}
{props.requiredButtons.includes("download") && (
<div
className={styles.menu}
onClick={() => setTriggerDropDownMenu(!triggerDropDownMenu)}
>
<div className={styles.dotMenu}>
<MenuIcon />
</div>
{triggerDropDownMenu && (
<div className={styles.dropDown}>
<div>
<div>
<OutlineDownloadIcon />
<p>Download Compose</p>
</div>
</div>
<div>
<div>
<OutlineDownloadIcon />
<p>Download Config</p>
</div>
</div>
<div>
<div>
<RestartIcon />
<p>Restart</p>
</div>
</div>
</div>
)}
</div>
)}
</div> </div>
</div> </div>
</> </>

View File

@@ -63,6 +63,7 @@
border-radius: 6px; border-radius: 6px;
border: 0.5px solid #8187ff; border: 0.5px solid #8187ff;
background: rgba(83, 89, 242, 0.25); background: rgba(83, 89, 242, 0.25);
color: white;
cursor: pointer; cursor: pointer;
} }
.button:hover { .button:hover {
@@ -126,7 +127,7 @@
} }
.dotMenu { .dotMenu {
display: flex; display: flex;
padding: 8px; padding: 7px;
align-items: center; align-items: center;
gap: 12px; gap: 12px;
border-radius: 6px; border-radius: 6px;
@@ -167,7 +168,6 @@
.dropDown > div:hover { .dropDown > div:hover {
border-radius: 4px; border-radius: 4px;
background: #3c4159; background: #3c4159;
background: color(display-p3 0.2392 0.2549 0.3412);
color: white; color: white;
} }
.dropDown > div:hover p { .dropDown > div:hover p {

View File

@@ -38,6 +38,7 @@ const Page = () => {
cancelButtonText="Cancel" cancelButtonText="Cancel"
topbarTitle="Create Credential" topbarTitle="Create Credential"
state="add" state="add"
requiredButtons={["title", "save"]}
/> />
{/* Create Crediantial Container */} {/* Create Crediantial Container */}
<div className={createCredStyle.createCredContainer}> <div className={createCredStyle.createCredContainer}>

View File

@@ -60,7 +60,11 @@ const CredentialsPage = () => {
<SuccessToast message="New Credential added successfully!" /> <SuccessToast message="New Credential added successfully!" />
<div className={globalStyle.mainContainer}> <div className={globalStyle.mainContainer}>
<div className={globalStyle.container}> <div className={globalStyle.container}>
<TopHeader buttonText="Add Credentials" topbarTitle="Credentials" /> <TopHeader
buttonText="Add Credentials"
topbarTitle="Credentials"
requiredButtons={["title", "add", "search", "env"]}
/>
<div className={styles.tableContainer}> <div className={styles.tableContainer}>
<table className={styles.table}> <table className={styles.table}>
<thead> <thead>

View File

@@ -58,7 +58,11 @@ const OrganizationPage = () => {
<div className={globalStyle.section}> <div className={globalStyle.section}>
<div className={globalStyle.mainContainer}> <div className={globalStyle.mainContainer}>
<div className={globalStyle.container}> <div className={globalStyle.container}>
<TopHeader buttonText="Add Organization" topbarTitle="Organization" /> <TopHeader
buttonText="Add Organization"
topbarTitle="Organization"
requiredButtons={["title", "add", "search"]}
/>
<div className={styles.tableContainer}> <div className={styles.tableContainer}>
<table className={styles.table}> <table className={styles.table}>
<thead> <thead>

View File

@@ -171,7 +171,11 @@ const ProjectsPage = () => {
<SuccessToast message="Project successfully added!" /> <SuccessToast message="Project successfully added!" />
<div className={globalStyle.mainContainer}> <div className={globalStyle.mainContainer}>
<div className={globalStyle.container}> <div className={globalStyle.container}>
<TopHeader buttonText="Create Project" topbarTitle="Project" /> <TopHeader
buttonText="Create Project"
topbarTitle="Project"
requiredButtons={["title", "add", "search"]}
/>
<div className={styles.tableContainer}> <div className={styles.tableContainer}>
<table className={styles.table}> <table className={styles.table}>
<thead> <thead>

View File

@@ -42,6 +42,7 @@ const AddServices = () => {
cancelButtonText="Cancel" cancelButtonText="Cancel"
state="view" state="view"
topbarTitle="View Services" topbarTitle="View Services"
requiredButtons={["back", "title", "edit", "download"]}
/> />
<div className={styles.contentContainer}> <div className={styles.contentContainer}>
<div className={styles.fieldsContainerCreateNew}> <div className={styles.fieldsContainerCreateNew}>

View File

@@ -34,6 +34,7 @@ const AddServices = () => {
cancelButtonText="Cancel" cancelButtonText="Cancel"
state="add" state="add"
topbarTitle="Create New Services" topbarTitle="Create New Services"
requiredButtons={["title", "save"]}
/> />
<div className={styles.contentContainer}> <div className={styles.contentContainer}>
<div className={styles.fieldsContainerCreateNew}> <div className={styles.fieldsContainerCreateNew}>

View File

@@ -99,6 +99,13 @@ const AddProject = () => {
topbarTitle="Services" topbarTitle="Services"
trigger={setTriggerAddServicesModal} trigger={setTriggerAddServicesModal}
triggerState={triggerAddServicesModal} triggerState={triggerAddServicesModal}
requiredButtons={[
"title",
"back",
"add-services",
"search",
"services-drop-down",
]}
/> />
<div className={styles.tableContainer}> <div className={styles.tableContainer}>
<table className={styles.table}> <table className={styles.table}>

View File

@@ -25,7 +25,12 @@ const page = () => {
<div className={globalStyle.section}> <div className={globalStyle.section}>
<div className={globalStyle.mainContainer}> <div className={globalStyle.mainContainer}>
<div className={globalStyle.container}> <div className={globalStyle.container}>
<TopHeader buttonText="" topbarTitle="View" state="view" /> <TopHeader
buttonText=""
topbarTitle="View"
state="view"
requiredButtons={["back", "title", "edit", "download"]}
/>
<div className={editRoleStyle.addRoleContainer}> <div className={editRoleStyle.addRoleContainer}>
{/* Input fields Container */} {/* Input fields Container */}
<div className={editRoleStyle.inputFieldContainer}> <div className={editRoleStyle.inputFieldContainer}>

View File

@@ -14,6 +14,7 @@ const page = () => {
cancelButtonText="Cancel" cancelButtonText="Cancel"
topbarTitle="Add Role" topbarTitle="Add Role"
state="add" state="add"
requiredButtons={["title", "save"]}
/> />
<div className={addRoleStyle.addUserContainer}> <div className={addRoleStyle.addUserContainer}>
{/* Input fields Container */} {/* Input fields Container */}

View File

@@ -49,7 +49,11 @@ const RolesPage = () => {
<SuccessToast message="New Role added successfully!" /> <SuccessToast message="New Role added successfully!" />
<div className={globalStyle.mainContainer}> <div className={globalStyle.mainContainer}>
<div className={globalStyle.container}> <div className={globalStyle.container}>
<TopHeader buttonText="Add Role" topbarTitle="Roles" /> <TopHeader
buttonText="Add Role"
topbarTitle="Roles"
requiredButtons={["title", "add", "search"]}
/>
{/* Users Table */} {/* Users Table */}
<div className={styles.tableContainer}> <div className={styles.tableContainer}>
<table className={styles.table}> <table className={styles.table}>

View File

@@ -28,7 +28,12 @@ const Page = () => {
<div className={globalStyle.section}> <div className={globalStyle.section}>
<div className={globalStyle.mainContainer}> <div className={globalStyle.mainContainer}>
<div className={globalStyle.container}> <div className={globalStyle.container}>
<TopHeader buttonText="" topbarTitle="View" state="view" /> <TopHeader
buttonText=""
topbarTitle="View"
state="view"
requiredButtons={["back", "title", "edit", "download"]}
/>
<div className={editUserStyle.addUserContainer}> <div className={editUserStyle.addUserContainer}>
{/* Input fields Container */} {/* Input fields Container */}
<div className={editUserStyle.inputFieldContainer}> <div className={editUserStyle.inputFieldContainer}>

View File

@@ -14,6 +14,7 @@ const page = () => {
cancelButtonText="Cancel" cancelButtonText="Cancel"
topbarTitle="Add User" topbarTitle="Add User"
state="add" state="add"
requiredButtons={["title", "save"]}
/> />
<div className={addUserStyle.addUserContainer}> <div className={addUserStyle.addUserContainer}>
{/* Input fields Container */} {/* Input fields Container */}

View File

@@ -36,8 +36,11 @@ const UsersPage = () => {
<SuccessToast message="New User added successfully" /> <SuccessToast message="New User added successfully" />
<div className={globalStyle.mainContainer}> <div className={globalStyle.mainContainer}>
<div className={globalStyle.container}> <div className={globalStyle.container}>
<TopHeader buttonText="Add User" topbarTitle="Users" /> <TopHeader
{/* Users Table */} buttonText="Add User"
topbarTitle="Users"
requiredButtons={["title", "add", "search"]}
/>
<div className={styles.tableContainer}> <div className={styles.tableContainer}>
<table className={styles.table}> <table className={styles.table}>
<thead className={styles.tableHeader}> <thead className={styles.tableHeader}>