Compare commits

..

2 Commits

15 changed files with 657 additions and 412 deletions

View File

@@ -6,97 +6,174 @@ import TopToolTip from "@/app/components/topToolTip/TopToolTip";
import globalStyle from "../../globalStyle.module.css";
import createAgentStyle from "./styles.module.css";
import Prompts from "@/app/components/prompts/Prompts";
import useAgentForm from "@/app/hooks/useAgentForm";
import Alert from "@/app/components/alerts/Alert";
import Checkbox from "@/app/components/customCheckbox/Checkbox";
const ViewAgentPage = () => {
const [isChecked, setIsChecked] = useState(false);
const handleCheckboxChange = (e) => {
setIsChecked(e.target.checked);
};
const [useVpn, setUseVpn] = useState(true);
const [enableLoki, setEnableLoki] = useState(true);
const {
register,
handleSubmit,
errors,
onSubmit,
triggerAlert,
setTriggerAlert,
} = useAgentForm();
return (
<div className={globalStyle.section}>
{triggerAlert && (
<Alert
setTriggerAlert={setTriggerAlert}
onClick={() => setEditState(true)}
title="Create New Agent"
/>
)}
<div className={globalStyle.mainContainer}>
<div className={globalStyle.container}>
<TopHeader
buttonText="Save"
cancelButtonText="Cancel"
topbarTitle="Update Agent"
topbarTitle="View Agent"
state="add"
requiredButtons={["update", "title"]}
requiredButtons={["edit", "back"]}
/>
{/* Create agent Container */}
<div className={createAgentStyle.createAgentContainer}>
<TopToolTip />
<div className={createAgentStyle.inputMainContainer}>
{/* Header */}
<div className={createAgentStyle.headerContainer}>
<div className={createAgentStyle.headerTxt}>
<p>Agent Details</p>
</div>
</div>
{/* Agent name input */}
<div className={createAgentStyle.inputContainer}>
{/* Label */}
<div className={createAgentStyle.labelContainer}>
<p>Agent Name</p>
{/* <p className={createAgentStyle.required}>*</p> */}
</div>
{/* Input Field */}
<TextField placeHolder="Enter agent name" />
<Prompts show={false} />
</div>
{/* Kubernetes API input */}
<div className={createAgentStyle.inputContainer}>
{/* Label */}
<div className={createAgentStyle.labelContainer}>
<p>Kubernetes API Proxy Name</p>
{/* <p className={createAgentStyle.required}>*</p> */}
</div>
{/* Input Field */}
<TextField placeHolder="Enter proxy name" />
<Prompts show={false} />
</div>
{/* Checkbox */}
<div className={createAgentStyle.checkboxMainContainer}>
<div className={createAgentStyle.checkboxContainer}>
<div className={createAgentStyle.checkbox}>
{/* Checkbox */}
<div className={createAgentStyle.check}>
<input
type="checkbox"
checked={isChecked}
onChange={handleCheckboxChange}
className={createAgentStyle.hiddenCheckbox}
/>
</div>
{/* List */}
<div className={createAgentStyle.list}>
<p className={createAgentStyle.placeholderTxt}>
Use Tailscale VPN
</p>
<p className={createAgentStyle.secondaryTxt}>
Enable Tailscale for secure private networking. When
enabled, <br /> the endpoint will be automatically
resolved from Tailscale.
</p>
</div>
<form
className={createAgentStyle.formContainer}
id="form"
onSubmit={handleSubmit(onSubmit)}
>
<div className={createAgentStyle.createAgentContainer}>
<div className={createAgentStyle.div}></div>
<div className={createAgentStyle.inputMainContainer}>
{/* AGENT FORM */}
<div className={createAgentStyle.headerContainer}>
<div className={createAgentStyle.headerTxt}>
<p>Agent Details</p>
</div>
</div>
</div>
{/* Agent endpoint */}
<div className={createAgentStyle.inputContainer}>
{/* Label */}
<div className={createAgentStyle.labelContainer}>
<p>Agent Endpoint</p>
{/* <p className={createAgentStyle.required}>*</p> */}
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Agent Name</p>
{/* <p className={createAgentStyle.required}>*</p> */}
</div>
<TextField
placeHolder="Enter agent name"
{...register("agentName", { required: true })}
hasError={!!errors.agentName}
/>
<Prompts show={false} />
</div>
{/* Input Field */}
<TextField placeHolder="e.g., http://agent-01.example.com:8080" />
<Prompts show={false} />
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Kubernetes API Proxy Name</p>
{/* <p className={createAgentStyle.required}>*</p> */}
</div>
<TextField
placeHolder="Enter proxy name"
{...register("proxyName", { required: true })}
hasError={!!errors.proxyName}
/>
<Prompts show={false} />
</div>
<Checkbox
checked={useVpn}
onChange={(e) => setUseVpn(e.target.checked)}
label="Use Tailscale VPN"
description={
<>
Enable Tailscale for secure private networking. When
enabled, <br />
the endpoint will be automatically resolved from
Tailscale.
</>
}
/>
{/* Agent endpoint */}
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Tailscale Device Prefix</p>
{/* <p className={createAgentStyle.required}>*</p> */}
</div>
<TextField
placeHolder="doks-onecbdev-agent"
{...register("agentEndpoint", { required: true })}
hasError={!!errors.agentEndpoint}
/>
<Prompts show={false} />
</div>
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Tailscale Port</p>
{/* <p className={createAgentStyle.required}>*</p> */}
</div>
<TextField
placeHolder="6969"
{...register("agentEndpoint", { required: true })}
hasError={!!errors.agentEndpoint}
/>
<Prompts show={false} />
</div>
</div>
<div className={createAgentStyle.lokiContainer}>
{/* Header */}
<div className={createAgentStyle.headerContainer}>
<div className={createAgentStyle.headerTxt}>
<p>Loki Integration (Optional)</p>
</div>
</div>
<Checkbox
checked={enableLoki}
onChange={(e) => setEnableLoki(e.target.checked)}
label="Enable Loki Logging"
description="Configure Loki for centralized logging and log streaming."
/>
{enableLoki && (
<>
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Loki Endpoint</p>
{/* <p className={createAgentStyle.required}>*</p> */}
</div>
<TextField
placeHolder="https://loki.project-moonshot.com/"
{...register("endpoint", { required: true })}
hasError={!!errors.endpoint}
/>
<Prompts show={false} />
</div>
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Tenant Name</p>
{/* <p className={createAgentStyle.required}>*</p> */}
</div>
<TextField
placeHolder="doks-dev"
{...register("tenantName", { required: true })}
hasError={!!errors.tenantName}
/>
<Prompts show={false} />
</div>
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Password</p>
{/* <p className={createAgentStyle.required}>*</p> */}
</div>
<TextField
placeHolder="Enter Password"
{...register("password", { required: true })}
hasError={!!errors.password}
/>
<Prompts show={false} />
</div>
</>
)}
</div>
</div>
</div>
</form>
</div>
</div>
</div>

View File

@@ -1,23 +1,31 @@
.createAgentContainer {
.formContainer {
display: flex;
flex-direction: column;
align-items: center;
gap: 48px;
align-items: flex-start;
gap: 10px;
flex: 1 0 0;
align-self: stretch;
}
.createAgentContainer {
display: flex;
justify-content: center;
align-items: flex-start;
align-self: stretch;
gap: 16px;
flex: 1 1 auto;
padding-top: 48px;
height: calc(100vh - 100px - 70px);
overflow-y: auto;
scrollbar-width: none;
}
.inputMainContainer {
display: flex;
padding: 24px;
flex-direction: column;
align-items: flex-start;
gap: 24px;
border-radius: 8px;
height: calc(100vh - 260px);
position: relative;
overflow: auto;
scrollbar-width: none;
}
.headerContainer {
display: flex;
@@ -34,9 +42,9 @@
flex: 1 0 0;
}
.headerTxt > p {
width: 163px;
/* width: 163px; */
align-self: stretch;
color: #d2d3e1;
color: color(display-p3 0.8235 0.8275 0.8784);
font-family: Inter;
font-size: 20px;
font-style: normal;
@@ -70,112 +78,11 @@
font-weight: 600;
}
.checkboxMainContainer {
.lokiContainer {
display: flex;
width: 548px;
padding: 24px;
flex-direction: column;
align-items: flex-start;
gap: 10px;
align-self: stretch;
}
.checkboxContainer {
display: flex;
align-items: flex-start;
align-self: stretch;
}
.checkbox {
display: flex;
padding: var(--Basic-Forms-Checkbox-Input-Sizing-Y-SM, 10px)
var(--Basic-Forms-Checkbox-Input-Sizing-X-SM, 12px);
align-items: flex-start;
gap: var(--Basic-Forms-Checkbox-Gap-Between, 16px);
flex: 1 0 0;
border-radius: var(--Basic-Forms-Checkbox-Border-Radius, 8px);
background: #1d1e2a;
background: color(display-p3 0.1137 0.1176 0.1608);
}
.check {
display: flex;
padding-top: var(--Basic-Forms-Checkbox-Inline-Y, 4px);
align-items: flex-start;
gap: var(--Basic-Forms-Checkbox-Inline-Gap-Between, 10px);
}
.hiddenCheckbox {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
width: 16px;
height: 16px;
display: flex;
justify-content: center;
align-items: center;
border-radius: var(--Basic-Forms-Checkbox-Check-Icon-Border-Radius, 4px);
border: 1px solid
var(--Basic-Forms-Checkbox-Check-Icon-Border-Border-Active-Color, #0067fd);
border: 1px solid
var(
--Basic-Forms-Checkbox-Check-Icon-Border-Border-Active-Color,
color(display-p3 0.1451 0.3882 0.9216)
);
cursor: pointer;
position: relative;
}
.hiddenCheckbox:checked {
border-radius: var(--Basic-Forms-Checkbox-Check-Icon-Border-Radius, 4px);
border: 1px solid
var(--Basic-Forms-Checkbox-Check-Icon-Border-Border-Active-Color, #0067fd);
border: 1px solid
var(
--Basic-Forms-Checkbox-Check-Icon-Border-Border-Active-Color,
color(display-p3 0.1451 0.3882 0.9216)
);
background: var(
--Basic-Forms-Checkbox-Check-Icon-Background-Bg-Active-Color,
#0067fd
);
background: var(
--Basic-Forms-Checkbox-Check-Icon-Background-Bg-Active-Color,
color(display-p3 0.1451 0.3882 0.9216)
);
}
.hiddenCheckbox::after {
content: "";
position: absolute;
inset: 0;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='8' viewBox='0 0 11 8' fill='none'%3E%3Cpath d='M9.83333 0.5L3.41667 6.91667L0.5 4' stroke='white' style='stroke:white;stroke-opacity:1;' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: center;
opacity: 0;
}
.hiddenCheckbox:checked::after {
opacity: 1;
}
.list {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 4px;
flex: 1 0 0;
}
.placeholderTxt {
align-self: stretch;
color: #d2d3e1;
color: color(display-p3 0.8235 0.8275 0.8784);
font-family: Inter;
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: 24px; /* 150% */
letter-spacing: 0.08px;
}
.secondaryTxt {
align-self: stretch;
color: #697281;
color: color(display-p3 0.4196 0.4471 0.502);
font-family: Inter;
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: 20px; /* 142.857% */
letter-spacing: 0.07px;
gap: 24px;
}

View File

@@ -8,13 +8,11 @@ import createAgentStyle from "./styles.module.css";
import Prompts from "@/app/components/prompts/Prompts";
import useAgentForm from "@/app/hooks/useAgentForm";
import Alert from "@/app/components/alerts/Alert";
import Checkbox from "@/app/components/customCheckbox/Checkbox";
const AddAgentPage = () => {
const [isChecked, setIsChecked] = useState(false);
const handleCheckboxChange = (e) => {
setIsChecked(e.target.checked);
};
const [useVpn, setUseVpn] = useState(false);
const [enableLoki, setEnableLoki] = useState(false);
const {
register,
handleSubmit,
@@ -42,94 +40,131 @@ const AddAgentPage = () => {
state="add"
requiredButtons={["title", "save"]}
/>
<TopToolTip />
{/* Create agent Container */}
<div className={createAgentStyle.createAgentContainer}>
<TopToolTip />
<form
className={createAgentStyle.inputMainContainer}
id="form"
onSubmit={handleSubmit(onSubmit)}
>
{/* Header */}
<div className={createAgentStyle.headerContainer}>
<div className={createAgentStyle.headerTxt}>
<p>Agent Details</p>
</div>
</div>
{/* Agent name input */}
<div className={createAgentStyle.inputContainer}>
{/* Label */}
<div className={createAgentStyle.labelContainer}>
<p>Agent Name</p>
<p className={createAgentStyle.required}>*</p>
</div>
{/* Input Field */}
<TextField
placeHolder="Enter agent name"
{...register("agentName", { required: true })}
hasError={!!errors.agentName}
/>
<Prompts show={false} />
</div>
{/* Kubernetes API input */}
<div className={createAgentStyle.inputContainer}>
{/* Label */}
<div className={createAgentStyle.labelContainer}>
<p>Kubernetes API Proxy Name</p>
<p className={createAgentStyle.required}>*</p>
</div>
{/* Input Field */}
<TextField
placeHolder="Enter proxy name"
{...register("proxyName", { required: true })}
hasError={!!errors.proxyName}
/>
<Prompts show={false} />
</div>
{/* Checkbox */}
<div className={createAgentStyle.checkboxMainContainer}>
<div className={createAgentStyle.checkboxContainer}>
<div className={createAgentStyle.checkbox}>
{/* Checkbox */}
<div className={createAgentStyle.check}>
<input
type="checkbox"
checked={isChecked}
onChange={handleCheckboxChange}
className={createAgentStyle.hiddenCheckbox}
/>
</div>
{/* List */}
<div className={createAgentStyle.list}>
<p className={createAgentStyle.placeholderTxt}>
Use Tailscale VPN
</p>
<p className={createAgentStyle.secondaryTxt}>
Enable Tailscale for secure private networking. When
enabled, <br /> the endpoint will be automatically
resolved from Tailscale.
</p>
</div>
<form
className={createAgentStyle.formContainer}
id="form"
onSubmit={handleSubmit(onSubmit)}
>
<div className={createAgentStyle.createAgentContainer}>
<div className={createAgentStyle.div}></div>
<div className={createAgentStyle.inputMainContainer}>
{/* AGENT FORM */}
<div className={createAgentStyle.headerContainer}>
<div className={createAgentStyle.headerTxt}>
<p>Agent Details</p>
</div>
</div>
</div>
{/* Agent endpoint */}
<div className={createAgentStyle.inputContainer}>
{/* Label */}
<div className={createAgentStyle.labelContainer}>
<p>Agent Endpoint</p>
<p className={createAgentStyle.required}>*</p>
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Agent Name</p>
<p className={createAgentStyle.required}>*</p>
</div>
<TextField
placeHolder="Enter agent name"
{...register("agentName", { required: true })}
hasError={!!errors.agentName}
/>
<Prompts show={false} />
</div>
{/* Input Field */}
<TextField
placeHolder="e.g., http://agent-01.example.com:8080"
{...register("agentEndpoint", { required: true })}
hasError={!!errors.agentEndpoint}
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Kubernetes API Proxy Name</p>
<p className={createAgentStyle.required}>*</p>
</div>
<TextField
placeHolder="Enter proxy name"
{...register("proxyName", { required: true })}
hasError={!!errors.proxyName}
/>
<Prompts show={false} />
</div>
<Checkbox
checked={useVpn}
onChange={(e) => setUseVpn(e.target.checked)}
label="Use Tailscale VPN"
description={
<>
Enable Tailscale for secure private networking. When
enabled, <br />
the endpoint will be automatically resolved from
Tailscale.
</>
}
/>
<Prompts show={false} />
{/* Agent endpoint */}
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Agent Endpoint</p>
<p className={createAgentStyle.required}>*</p>
</div>
<TextField
placeHolder="e.g., http://agent-01.example.com:8080"
{...register("agentEndpoint", { required: true })}
hasError={!!errors.agentEndpoint}
/>
<Prompts show={false} />
</div>
</div>
</form>
</div>
<div className={createAgentStyle.lokiContainer}>
{/* Header */}
<div className={createAgentStyle.headerContainer}>
<div className={createAgentStyle.headerTxt}>
<p>Loki Integration (Optional)</p>
</div>
</div>
<Checkbox
checked={enableLoki}
onChange={(e) => setEnableLoki(e.target.checked)}
label="Enable Loki Logging"
description="Configure Loki for centralized logging and log streaming."
/>
{enableLoki && (
<>
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Loki Endpoint</p>
{/* <p className={createAgentStyle.required}>*</p> */}
</div>
<TextField
placeHolder="https://loki.project-moonshot.com/"
{...register("endpoint", { required: true })}
hasError={!!errors.endpoint}
/>
<Prompts show={false} />
</div>
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Tenant Name</p>
{/* <p className={createAgentStyle.required}>*</p> */}
</div>
<TextField
placeHolder="doks-dev"
{...register("tenantName", { required: true })}
hasError={!!errors.tenantName}
/>
<Prompts show={false} />
</div>
<div className={createAgentStyle.inputContainer}>
<div className={createAgentStyle.labelContainer}>
<p>Password</p>
{/* <p className={createAgentStyle.required}>*</p> */}
</div>
<TextField
placeHolder="Enter Password"
{...register("password", { required: true })}
hasError={!!errors.password}
/>
<Prompts show={false} />
</div>
</>
)}
</div>
</div>
</form>
</div>
</div>
</div>

View File

@@ -1,24 +1,32 @@
.createAgentContainer {
.formContainer {
display: flex;
flex-direction: column;
align-items: center;
gap: 48px;
align-items: flex-start;
gap: 10px;
flex: 1 0 0;
padding-top: 48px;
align-self: stretch;
}
.createAgentContainer {
display: flex;
justify-content: center;
align-items: flex-start;
align-self: stretch;
/* Ibalhin ni ang padding sa formcontainer maoang nasa figma */
gap: 16px;
flex: 1 1 auto;
height: calc(100vh - 100px - 48px - 110px);
overflow-y: auto;
scrollbar-width: none;
}
.inputMainContainer {
display: flex;
padding: 24px;
flex-direction: column;
align-items: flex-start;
gap: 24px;
border-radius: 8px;
/* Remove ni kung mo ingon si sir grills */
height: calc(100vh - 260px);
position: relative;
overflow: auto;
scrollbar-width: none;
}
.headerContainer {
display: flex;
@@ -35,9 +43,9 @@
flex: 1 0 0;
}
.headerTxt > p {
width: 163px;
/* width: 163px; */
align-self: stretch;
color: #d2d3e1;
color: color(display-p3 0.8235 0.8275 0.8784);
font-family: Inter;
font-size: 20px;
font-style: normal;
@@ -71,112 +79,11 @@
font-weight: 600;
}
.checkboxMainContainer {
.lokiContainer {
display: flex;
width: 548px;
padding: 24px;
flex-direction: column;
align-items: flex-start;
gap: 10px;
align-self: stretch;
}
.checkboxContainer {
display: flex;
align-items: flex-start;
align-self: stretch;
}
.checkbox {
display: flex;
padding: var(--Basic-Forms-Checkbox-Input-Sizing-Y-SM, 10px)
var(--Basic-Forms-Checkbox-Input-Sizing-X-SM, 12px);
align-items: flex-start;
gap: var(--Basic-Forms-Checkbox-Gap-Between, 16px);
flex: 1 0 0;
border-radius: var(--Basic-Forms-Checkbox-Border-Radius, 8px);
background: #1d1e2a;
background: color(display-p3 0.1137 0.1176 0.1608);
}
.check {
display: flex;
padding-top: var(--Basic-Forms-Checkbox-Inline-Y, 4px);
align-items: flex-start;
gap: var(--Basic-Forms-Checkbox-Inline-Gap-Between, 10px);
}
.hiddenCheckbox {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
width: 16px;
height: 16px;
display: flex;
justify-content: center;
align-items: center;
border-radius: var(--Basic-Forms-Checkbox-Check-Icon-Border-Radius, 4px);
border: 1px solid
var(--Basic-Forms-Checkbox-Check-Icon-Border-Border-Active-Color, #0067fd);
border: 1px solid
var(
--Basic-Forms-Checkbox-Check-Icon-Border-Border-Active-Color,
color(display-p3 0.1451 0.3882 0.9216)
);
cursor: pointer;
position: relative;
}
.hiddenCheckbox:checked {
border-radius: var(--Basic-Forms-Checkbox-Check-Icon-Border-Radius, 4px);
border: 1px solid
var(--Basic-Forms-Checkbox-Check-Icon-Border-Border-Active-Color, #0067fd);
border: 1px solid
var(
--Basic-Forms-Checkbox-Check-Icon-Border-Border-Active-Color,
color(display-p3 0.1451 0.3882 0.9216)
);
background: var(
--Basic-Forms-Checkbox-Check-Icon-Background-Bg-Active-Color,
#0067fd
);
background: var(
--Basic-Forms-Checkbox-Check-Icon-Background-Bg-Active-Color,
color(display-p3 0.1451 0.3882 0.9216)
);
}
.hiddenCheckbox::after {
content: "";
position: absolute;
inset: 0;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='8' viewBox='0 0 11 8' fill='none'%3E%3Cpath d='M9.83333 0.5L3.41667 6.91667L0.5 4' stroke='white' style='stroke:white;stroke-opacity:1;' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: center;
opacity: 0;
}
.hiddenCheckbox:checked::after {
opacity: 1;
}
.list {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 4px;
flex: 1 0 0;
}
.placeholderTxt {
align-self: stretch;
color: #d2d3e1;
color: color(display-p3 0.8235 0.8275 0.8784);
font-family: Inter;
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: 24px; /* 150% */
letter-spacing: 0.08px;
}
.secondaryTxt {
align-self: stretch;
color: #697281;
color: color(display-p3 0.4196 0.4471 0.502);
font-family: Inter;
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: 20px; /* 142.857% */
letter-spacing: 0.07px;
gap: 24px;
}

View File

@@ -0,0 +1,32 @@
import React from "react";
import styles from "./styles.module.css";
const Checkbox = ({ checked, onChange, label, description }) => {
return (
<>
{/* Checkbox */}
<div className={styles.checkboxMainContainer}>
<div className={styles.checkboxContainer}>
<div className={styles.checkbox}>
{/* Checkbox */}
<div className={styles.check}>
<input
type="checkbox"
checked={checked}
onChange={onChange}
className={styles.hiddenCheckbox}
/>
</div>
{/* List */}
<div className={styles.list}>
<p className={styles.placeholderTxt}>{label}</p>
<p className={styles.secondaryTxt}>{description}</p>
</div>
</div>
</div>
</div>
</>
);
};
export default Checkbox;

View File

@@ -0,0 +1,105 @@
.checkboxMainContainer {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 10px;
align-self: stretch;
}
.checkboxContainer {
display: flex;
align-items: flex-start;
align-self: stretch;
}
.checkbox {
display: flex;
padding: var(--Basic-Forms-Checkbox-Input-Sizing-Y-SM, 10px)
var(--Basic-Forms-Checkbox-Input-Sizing-X-SM, 12px);
align-items: flex-start;
gap: var(--Basic-Forms-Checkbox-Gap-Between, 16px);
flex: 1 0 0;
border-radius: var(--Basic-Forms-Checkbox-Border-Radius, 8px);
background: #1d1e2a;
background: color(display-p3 0.1137 0.1176 0.1608);
}
.check {
display: flex;
padding-top: var(--Basic-Forms-Checkbox-Inline-Y, 4px);
align-items: flex-start;
gap: var(--Basic-Forms-Checkbox-Inline-Gap-Between, 10px);
}
.hiddenCheckbox {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
width: 16px;
height: 16px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
position: relative;
border-radius: var(--Basic-Forms-Checkbox-Check-Icon-Border-Radius, 4px);
border: 1px solid
var(--Basic-Forms-Checkbox-Check-Icon-Border-Border-Color, #e5e7eb);
background: var(--Basic-Forms-Checkbox-Check-Icon-Background-Bg-Color, #fff);
}
.hiddenCheckbox:checked {
border-radius: var(--Basic-Forms-Checkbox-Check-Icon-Border-Radius, 4px);
border: 1px solid
var(--Basic-Forms-Checkbox-Check-Icon-Border-Border-Active-Color, #0067fd);
border: 1px solid
var(
--Basic-Forms-Checkbox-Check-Icon-Border-Border-Active-Color,
color(display-p3 0.1451 0.3882 0.9216)
);
background: var(
--Basic-Forms-Checkbox-Check-Icon-Background-Bg-Active-Color,
#0067fd
);
background: var(
--Basic-Forms-Checkbox-Check-Icon-Background-Bg-Active-Color,
color(display-p3 0.1451 0.3882 0.9216)
);
}
.hiddenCheckbox::after {
content: "";
position: absolute;
inset: 0;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='8' viewBox='0 0 11 8' fill='none'%3E%3Cpath d='M9.83333 0.5L3.41667 6.91667L0.5 4' stroke='white' style='stroke:white;stroke-opacity:1;' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: center;
opacity: 0;
}
.hiddenCheckbox:checked::after {
opacity: 1;
}
.list {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 4px;
flex: 1 0 0;
}
.placeholderTxt {
align-self: stretch;
color: #d2d3e1;
color: color(display-p3 0.8235 0.8275 0.8784);
font-family: Inter;
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: 24px; /* 150% */
letter-spacing: 0.08px;
}
.secondaryTxt {
align-self: stretch;
color: #697281;
font-family: Inter;
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: 20px; /* 142.857% */
letter-spacing: 0.07px;
}

View File

@@ -6,7 +6,6 @@ import useIsMobile from "@/app/hooks/useIsMobile";
const Profile = () => {
const isMobile = useIsMobile();
const [open, setOpen] = useState(false);
const [user, setUser] = useState("");
const sampleData = [
{
name: "JM Grills",

View File

@@ -22,7 +22,6 @@
align-items: flex-start;
border-radius: 6px;
background: #1d1e2a;
background: color(display-p3 0.1137 0.1176 0.1608);
}
.header {
display: flex;

View File

@@ -0,0 +1,28 @@
import DeleteIcon from "@/app/components/icons/delete";
import React from "react";
const Card = (props) => {
return (
<div className={styles.cardContainer} {...props}>
<div className={styles.cardDetails}>
<div className={styles.list}>
<p>Name</p>
<p>{props?.user?.email}</p>
</div>
<div className={styles.list}>
<p>Organization ID</p>
<p>{props?.user?.fullName}</p>
</div>
<div className={styles.list}>
<p>Permissions</p>
<p>{props?.user?.createdAt}</p>
</div>
</div>
<div className={styles.cardAction}>
<DeleteIcon />
</div>
</div>
);
};
export default Card;

View File

@@ -0,0 +1,43 @@
.cardContainer {
display: flex;
padding: 16px 0;
align-items: flex-start;
gap: 16px;
align-self: stretch;
border-bottom: 1px solid #2c2d3d;
cursor: pointer;
}
.cardDetails {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
flex: 1 0 0;
}
.list {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 5px;
align-self: stretch;
}
.list p {
color: #85869b;
font-family: Inter;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
.list p:nth-child(2) {
color: #eeeffd;
font-family: Inter;
font-size: 16px;
font-weight: 500;
}
.cardAction {
display: flex;
align-items: center;
gap: 17px;
}

View File

@@ -22,7 +22,6 @@
padding: 12px 24px;
text-align: left;
color: #85869b;
color: color(display-p3 0.5216 0.5255 0.6);
font-family: Inter;
font-size: 13px;
font-style: normal;
@@ -41,7 +40,6 @@
.tableBody td {
padding: 12px 24px;
color: #eeeffd;
color: color(display-p3 0.9333 0.9373 0.9882);
font-family: Inter;
font-size: 13px;
font-style: normal;
@@ -55,9 +53,7 @@
}
.tableBody tr:hover {
border-bottom: 1px solid rgba(129, 135, 255, 0.25);
border-bottom: 1px solid color(display-p3 0.5098 0.5294 1 / 0.25);
background: rgba(129, 135, 255, 0.05);
background: color(display-p3 0.5098 0.5294 1 / 0.05);
}
.tableActions {
@@ -68,3 +64,16 @@
gap: 12px;
align-self: stretch;
}
/* Mobile */
.cardContainer {
display: flex;
padding: 0 16px;
padding-bottom: 50px;
height: calc(100vh - 170px);
flex-direction: column;
align-items: flex-start;
gap: 12px;
align-self: stretch;
overflow: auto;
}

View File

@@ -8,25 +8,25 @@ import ViewIcon from "../components/icons/view";
import DeleteIcon from "../components/icons/delete";
import SuccessToast from "../components/toast/success/successToast";
import ActionButton from "../components/actionButton/ActionButton";
import useIsMobile from "../hooks/useIsMobile";
import MobileSearchBar from "../components/mobileSearchBar/MobileSearchBar";
import Card from "./user-card/Card";
const UsersPage = () => {
const router = useRouter();
const isMobile = useIsMobile();
const sampleData = [
{
id: 1,
email: "nino.moonshot@gmail.com",
fullName: "Nino Paul Cervantes",
createdAt: "2024-10-21 08:01:31.474 +0000 UTC",
},
{
id: 2,
email: "nino.moonshot@gmail.com",
fullName: "Nino Paul Cervantes",
createdAt: "2024-10-21 08:01:31.474 +0000 UTC",
},
{
id: 3,
email: "nino.moonshot@gmail.com",
fullName: "Nino Paul Cervantes",
createdAt: "2024-10-21 08:01:31.474 +0000 UTC",
@@ -42,6 +42,20 @@ const UsersPage = () => {
topbarTitle="Users"
requiredButtons={["title", "add", "search"]}
/>
<div className={styles.cardContainer}>
<MobileSearchBar />
{sampleData.map((user, index) => {
return (
<Card
user={user}
key={index}
onClick={() => router.push(`/users/${index}`)}
/>
);
})}
</div>
<div className={styles.tableContainer}>
<table className={styles.table}>
<thead className={styles.tableHeader}>
@@ -56,8 +70,8 @@ const UsersPage = () => {
{sampleData.map((user, index) => {
return (
<tr
key={user.id}
onClick={() => router.push(`/users/${user.id}`)}
key={index}
onClick={() => router.push(`/users/${index}`)}
>
<td>{user.email}</td>
<td>{user.fullName}</td>

View File

@@ -4,7 +4,6 @@
position: relative;
overflow: auto;
}
/* Table */
.table {
width: 100%;
@@ -22,9 +21,9 @@
padding: 12px 24px;
text-align: left;
color: #85869b;
color: color(display-p3 0.5216 0.5255 0.6);
font-family: Inter;
font-size: 13px;
font-size: var(--table-font-size);
font-style: normal;
flex: 1 0 0;
font-weight: 500;
@@ -40,9 +39,8 @@
.tableBody td {
padding: 12px 24px;
color: #eeeffd;
color: color(display-p3 0.9333 0.9373 0.9882);
font-family: Inter;
font-size: 13px;
font-size: var(--table-font-size);
font-style: normal;
font-weight: 500;
line-height: normal;
@@ -54,9 +52,7 @@
}
.tableBody tr:hover {
border-bottom: 1px solid rgba(129, 135, 255, 0.25);
border-bottom: 1px solid color(display-p3 0.5098 0.5294 1 / 0.25);
background: rgba(129, 135, 255, 0.05);
background: color(display-p3 0.5098 0.5294 1 / 0.05);
}
.tableActions {
@@ -67,3 +63,24 @@
gap: 12px;
align-self: stretch;
}
.cardContainer {
display: none;
}
@media (max-width: 768px) {
.cardContainer {
display: flex;
padding: 0 16px;
padding-bottom: 50px;
height: calc(100vh - 170px);
flex-direction: column;
align-items: flex-start;
gap: 12px;
align-self: stretch;
overflow: auto;
background-color: red;
}
.tableContainer {
display: none;
}
}

View File

@@ -0,0 +1,29 @@
import DeleteIcon from "@/app/components/icons/delete";
import React from "react";
import styles from "./styles.module.css";
const Card = (props) => {
return (
<div className={styles.cardContainer} {...props}>
<div className={styles.cardDetails}>
<div className={styles.list}>
<p>Email</p>
<p>{props?.user?.email}</p>
</div>
<div className={styles.list}>
<p>Full Name</p>
<p>{props?.user?.fullName}</p>
</div>
<div className={styles.list}>
<p>Date Created</p>
<p>{props?.user?.createdAt}</p>
</div>
</div>
<div className={styles.cardAction}>
<DeleteIcon />
</div>
</div>
);
};
export default Card;

View File

@@ -0,0 +1,44 @@
.cardContainer {
display: flex;
padding: 16px 0;
align-items: flex-start;
gap: 16px;
align-self: stretch;
border-bottom: 1px solid #2c2d3d;
cursor: pointer;
background-color: green;
}
.cardDetails {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
flex: 1 0 0;
}
.list {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 5px;
align-self: stretch;
}
.list p {
color: #85869b;
font-family: Inter;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
.list p:nth-child(2) {
color: #eeeffd;
font-family: Inter;
font-size: 16px;
font-weight: 500;
}
.cardAction {
display: flex;
align-items: center;
gap: 17px;
}