Add components

This commit is contained in:
Laux Dev
2026-03-02 15:33:21 +08:00
parent f16b78834c
commit 1023990822
20 changed files with 1234 additions and 164 deletions

View File

@@ -35,7 +35,7 @@
}
.check:checked + .switch .knob {
transform: translateX(75%);
transform: translateX(78%);
background-color: white;
}

View File

@@ -25,6 +25,15 @@
border: 1px solid #959aff;
background: rgba(75, 79, 109, 0.25);
}
.input:active::placeholder,
.input:focus::placeholder {
color: #4b4f6d;
font-family: Inter;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
.input:hover {
background: rgba(75, 79, 109, 0.25);
}

View File

@@ -0,0 +1,28 @@
const ArrowDownIcon = ({
width = 18,
height = 18,
color = "#4C4F6B",
...props
}) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
viewBox="0 0 18 18"
fill="none"
{...props}
>
<path
d="M1.55859 5.2793L9.00047 12.7212L16.4423 5.2793"
stroke={color}
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
export default ArrowDownIcon;

View File

@@ -0,0 +1,38 @@
import React from "react";
const WarningIcon = (props) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={20}
height={20}
viewBox="0 0 20 20"
fill="none"
{...props}
>
<path
d="M2.5 10C2.5 10.9849 2.69399 11.9602 3.0709 12.8701C3.44781 13.7801 4.00026 14.6069 4.6967 15.3033C5.39314 15.9997 6.21993 16.5522 7.12987 16.9291C8.03982 17.306 9.01509 17.5 10 17.5C10.9849 17.5 11.9602 17.306 12.8701 16.9291C13.7801 16.5522 14.6069 15.9997 15.3033 15.3033C15.9997 14.6069 16.5522 13.7801 16.9291 12.8701C17.306 11.9602 17.5 10.9849 17.5 10C17.5 8.01088 16.7098 6.10322 15.3033 4.6967C13.8968 3.29018 11.9891 2.5 10 2.5C8.01088 2.5 6.10322 3.29018 4.6967 4.6967C3.29018 6.10322 2.5 8.01088 2.5 10Z"
stroke="#CCA04F"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M10 6.66699V10.0003"
stroke="#CCA04F"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M10 13.333H10.0083"
stroke="#CCA04F"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
export default WarningIcon;

View File

@@ -0,0 +1,71 @@
"use client";
import React, { useState, useRef, useEffect } from "react";
import styles from "./styles.module.css";
import ArrowDownIcon from "../icons/arrowDown";
const SelectField = ({ label, options, ...props }) => {
const [showOptions, setShowOptions] = useState(false);
const [dropUp, setDropUp] = useState(false);
const selectRef = useRef(null);
const [currentSelected, setCurrentSelected] = useState({
label: label,
value: "",
});
useEffect(() => {
if (showOptions && selectRef.current) {
const rect = selectRef.current.getBoundingClientRect();
const spaceBelow = window.innerHeight - rect.bottom;
const spaceAbove = rect.top;
const dropdownHeight = 150;
if (spaceBelow < dropdownHeight && spaceAbove > dropdownHeight) {
setDropUp(true);
} else {
setDropUp(false);
}
}
}, [showOptions]);
return (
<div
ref={selectRef}
className={styles.select}
onClick={() => setShowOptions(!showOptions)}
{...props}
>
<label
className={`${styles.label} ${currentSelected.value ? styles.selected : ""}`}
>
{currentSelected.label}
</label>
<ArrowDownIcon />
{showOptions && (
<div
className={`${styles.optionsContainer} ${
dropUp ? styles.dropUp : ""
}`}
>
{options.map((opt, key) => {
return (
<div
key={key}
onClick={() => {
setCurrentSelected(opt);
setShowOptions(false);
}}
>
<p>{opt.label}</p>
</div>
);
})}
</div>
)}
</div>
);
};
export default SelectField;

View File

@@ -0,0 +1,83 @@
.select {
display: flex;
padding: 12px;
align-items: flex-start;
align-items: center;
justify-content: space-between;
gap: 10px;
align-self: stretch;
border-radius: 4px;
border: 1px solid #4b4f6d;
background-color: transparent;
position: relative;
}
.label {
color: #858699;
font-family: Inter;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
.selected {
color: white;
}
.optionsContainer {
display: flex;
padding: 6px;
flex-direction: column;
align-items: flex-start;
align-self: stretch;
position: absolute;
width: 100%;
left: 0;
border-radius: 6px;
border: 1px solid #353a4c;
background: #282b39;
animation-name: showDD;
animation-duration: 200ms;
z-index: 20;
}
@keyframes showDD {
0% {
opacity: 0;
transform: translateY(-10%);
}
100% {
opacity: 1;
transform: translateY(0%);
}
}
.optionsContainer > div {
display: flex;
padding: 8px;
align-items: center;
gap: 10px;
align-self: stretch;
border-radius: 4px;
}
.optionsContainer p {
color: #acb0ff;
font-family: Inter;
font-size: 18px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
.optionsContainer > div:hover,
.optionsContainer > div:hover p {
background: #3c4159;
color: white;
}
.optionsContainer {
top: 0%;
margin-top: 6px;
}
/* When flipping upward */
.dropUp {
bottom: 0%;
top: auto;
margin-bottom: 6px;
}

View File

@@ -44,7 +44,7 @@
display: flex;
justify-content: flex-end;
align-items: center;
gap: 10px;
gap: 5px;
}
.searchBarContainer {
display: flex;
@@ -55,14 +55,14 @@
}
.button {
display: flex;
padding: 8px 12px;
padding: 7px 15px;
justify-content: center;
align-items: center;
gap: 8px;
gap: 10px;
border-radius: 6px;
border-radius: 6px;
border: 0.5px solid #8187ff;
background: rgba(83, 89, 242, 0.25);
cursor: pointer;
}
.button:hover {
background: linear-gradient(180deg, #5359f2 0%, #2e3288 100%);

View File

@@ -3,6 +3,9 @@ import globalStyle from "../../globalStyle.module.css";
import TopHeader from "@/app/components/topHeader/TopHeader";
import styles from "./styles.module.css";
import TopToolTip from "@/app/components/topToolTip/TopToolTip";
import TextField from "@/app/components/fields/textfield";
import SelectField from "@/app/components/select/SelectField";
import WarningIcon from "@/app/components/icons/warning";
const AddProject = () => {
return (
<div className={globalStyle.section}>
@@ -24,37 +27,9 @@ const AddProject = () => {
</p>
</div>
<div className={styles.inputField}>
<input type="text" placeholder="Enter project name" />
<TextField placeHolder="Enter project name" />
<div className={styles.prompts}>
<svg
xmlns="http://www.w3.org/2000/svg"
width={20}
height={20}
viewBox="0 0 20 20"
fill="none"
>
<path
d="M2.5 10C2.5 10.9849 2.69399 11.9602 3.0709 12.8701C3.44781 13.7801 4.00026 14.6069 4.6967 15.3033C5.39314 15.9997 6.21993 16.5522 7.12987 16.9291C8.03982 17.306 9.01509 17.5 10 17.5C10.9849 17.5 11.9602 17.306 12.8701 16.9291C13.7801 16.5522 14.6069 15.9997 15.3033 15.3033C15.9997 14.6069 16.5522 13.7801 16.9291 12.8701C17.306 11.9602 17.5 10.9849 17.5 10C17.5 8.01088 16.7098 6.10322 15.3033 4.6967C13.8968 3.29018 11.9891 2.5 10 2.5C8.01088 2.5 6.10322 3.29018 4.6967 4.6967C3.29018 6.10322 2.5 8.01088 2.5 10Z"
stroke="#CCA04F"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M10 6.66699V10.0003"
stroke="#CCA04F"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M10 13.333H10.0083"
stroke="#CCA04F"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
<WarningIcon />
<p>The name is already in used. You can try another.</p>
</div>
</div>
@@ -66,7 +41,7 @@ const AddProject = () => {
</p>
</div>
<div className={styles.inputField}>
<input type="text" placeholder="Version" />
<TextField placeHolder="Version" />
</div>
</div>
<div className={styles.inputGroup}>
@@ -76,9 +51,14 @@ const AddProject = () => {
</p>
</div>
<div className={styles.inputField}>
<select name="" id="">
<option value="">Select</option>
</select>
<SelectField
label="Select"
options={[
{ label: "Option", value: "option" },
{ label: "Option 1", value: "option 1" },
{ label: "Option 2", value: "option 2" },
]}
/>
</div>
</div>
<div className={styles.inputGroup}>
@@ -88,17 +68,14 @@ const AddProject = () => {
</p>
</div>
<div className={styles.inputField}>
<select name="" id="">
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<SelectField
label="Select"
options={[
{ label: "Option", value: "option" },
{ label: "Option 1", value: "option 1" },
{ label: "Option 2", value: "option 2" },
]}
/>
</div>
</div>
</div>

View File

@@ -0,0 +1,396 @@
"use client";
import React, { useState } from "react";
import globalStyle from "@/app/globalStyle.module.css";
import TopHeader from "@/app/components/topHeader/TopHeader";
import styles from "./styles.module.css";
import variableStyles from "./variableStyles.module.css";
import TextField from "@/app/components/fields/textfield";
import AddVariableModal from "../variableModals/AddVariableModal/AddVariableModal";
import AddVolumeModal from "../variableModals/AddVolumes/AddVolumeModal";
import AddConfigMapModal from "../variableModals/AddConfigMap/AddConfigMapModal";
import CustomCheckbox from "@/app/components/checkbox/CheckBox";
import DeleteIcon from "@/app/components/icons/delete";
import SelectField from "@/app/components/select/SelectField";
const AddServices = () => {
const [triggerVariableDropDown, setTriggerVariableDropDown] = useState(false);
const [triggerAddVariable, setTriggerAddVariable] = useState(false);
const [triggerAddVolume, setTriggerAddVolume] = useState(false);
const [triggeAddConfigMap, setTriggerAddConfigMap] = useState(false);
const sampleData = [
{ id: 1, key: "REQUEST_SERVICE_GRPC", value: "request-service:50053" },
{ id: 1, key: "REQUEST_SERVICE_GRPC", value: "request-service:50053" },
{ id: 1, key: "REQUEST_SERVICE_GRPC", value: "request-service:50053" },
{ id: 1, key: "REQUEST_SERVICE_GRPC", value: "request-service:50053" },
{ id: 1, key: "REQUEST_SERVICE_GRPC", value: "request-service:50053" },
{ id: 1, key: "REQUEST_SERVICE_GRPC", value: "request-service:50053" },
];
return (
<div className={globalStyle.section}>
{triggerAddVariable && (
<AddVariableModal setTriggerAddVariable={setTriggerAddVariable} />
)}
{triggerAddVolume && (
<AddVolumeModal setTriggerAddVolume={setTriggerAddVolume} />
)}
{triggeAddConfigMap && (
<AddConfigMapModal setTriggerAddConfigMap={setTriggerAddConfigMap} />
)}
<div className={globalStyle.mainContainer}>
<div className={globalStyle.container}>
<TopHeader
buttonText="Save"
cancelButtonText="Cancel"
state="view"
topbarTitle="View Services"
/>
<div className={styles.contentContainer}>
<div className={styles.fieldsContainerCreateNew}>
<div className={styles.projectDetails}>
<div className={styles.projectDetailsHeader}>
<p>Project Details</p>
</div>
<div className={styles.fieldsCreateNew}>
<div>
<div>
<p>Name</p>
<TextField placeHolder="Enter service name" />
</div>
<div>
<p>Version</p>
<TextField placeHolder="Service version" />
</div>
</div>
<div>
<div>
<p>
Image <span>(Optional)</span>
</p>
<TextField placeHolder="Enter image name" />
</div>
</div>
<div>
<div>
<p>Port</p>
<TextField placeHolder="Enter port" />
</div>
</div>
<div>
<div>
<p>Ingress</p>
<SelectField
label="Select"
options={[
{ label: "Option", value: "option" },
{ label: "Option 1", value: "option 1" },
{ label: "Option 2", value: "option 2" },
]}
/>
</div>
<div>
<p>Ingress</p>
<SelectField
label="Select"
options={[
{ label: "Option", value: "option" },
{ label: "Option 1", value: "option 1" },
{ label: "Option 2", value: "option 2" },
]}
/>
</div>
</div>
</div>
</div>
<div className={styles.resource}>
<div className={styles.projectDetailsHeader}>
<p>Resource</p>
</div>
<div className={styles.resourceFields}>
<div>
<div>
<p>CPU Request (MB)</p>
<TextField placeHolder="250" />
</div>
<div>
<p>CPU Limit (MB)</p>
<TextField placeHolder="250" />
</div>
</div>
<div>
<div>
<p>Memory Request (MB)</p>
<TextField placeHolder="250" />
</div>
<div>
<p>Memory Limit (MB)</p>
<TextField placeHolder="500" />
</div>
</div>
</div>
</div>
<div className={styles.additionalDetails}>
<div>
<div>
<div className={styles.additionalDetailsHeader}>
<div>
<p>Auto Scaling</p>
<CustomCheckbox id="scalingCheckBox" />
</div>
</div>
<div className={styles.additionalDetailsFields}>
<div>
<div>
<div>
<p>Minimum pods</p>
<TextField placeHolder="1" />
</div>
<div>
<p>Maximum pods</p>
<TextField placeHolder="1" />
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div className={styles.additionalDetailsHeader}>
<div>
<p>Readiness</p>
<CustomCheckbox id="readiNessCheckBox" />
</div>
</div>
<div className={styles.additionalDetailsFields}>
<div>
<div>
<div>
<p>Readiness Path</p>
<TextField placeHolder="Enter Readiness path" />
</div>
<div>
<p>Readiness Port</p>
<TextField placeHolder="Enter Readiness port" />
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div className={styles.additionalDetailsHeader}>
<div>
<p>Liveness</p>
<CustomCheckbox id="liveNessCheckBox" />
</div>
</div>
<div className={styles.additionalDetailsFields}>
<div>
<div>
<div>
<p>Liveness Path</p>
<TextField placeHolder="Enter liveness path" />
</div>
<div>
<p>Liveness Port</p>
<TextField placeHolder="Enter liveness port" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div className={variableStyles.variables}>
<div className={variableStyles.variablesHeader}>
<div>
<div className={variableStyles.searchContainer}>
<div className={variableStyles.searchInputGroup}>
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
>
<g clipPath="url(#clip0)">
<path
d="M8.66099 16.0271C12.7292 16.0271 16.0271 12.7292 16.0271 8.66099C16.0271 4.59282 12.7292 1.29492 8.66099 1.29492C4.59282 1.29492 1.29492 4.59282 1.29492 8.66099C1.29492 12.7292 4.59282 16.0271 8.66099 16.0271Z"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M18.7051 18.7061L14.0176 14.0186"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
</svg>
<input type="text" placeholder="Search" />
</div>
</div>
<div className={variableStyles.variablesHeaderDropDown}>
<div
className={variableStyles.variableHeaderDropdownButton}
onClick={() =>
setTriggerVariableDropDown(!triggerVariableDropDown)
}
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
>
<path
d="M12 5.29199V18.7087"
stroke="white"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M5.29102 12H18.7077"
stroke="white"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</div>
{triggerVariableDropDown && (
<div className={variableStyles.dropDownContainer}>
<div
onClick={() => {
setTriggerAddVariable(true);
setTriggerVariableDropDown(
!triggerVariableDropDown,
);
}}
>
<p>Environment Variables</p>
</div>
<div
onClick={() => {
setTriggerAddVolume(true);
setTriggerVariableDropDown(
!triggerVariableDropDown,
);
}}
>
<p>Volumes</p>
</div>
<div
onClick={() => {
setTriggerAddConfigMap(true);
setTriggerVariableDropDown(
!triggerVariableDropDown,
);
}}
>
<p>Config Maps</p>
</div>
</div>
)}
</div>
</div>
</div>
<div className={variableStyles.variablesContentContainer}>
<div>
<div className={variableStyles.variablesContent}>
<div
className={variableStyles.environmentVariablesContainer}
>
<div
className={variableStyles.environmentVariablesHeader}
>
<p>Environment Variables</p>
</div>
<div className={variableStyles.envVariablesHeader}>
<div>
<p>Key</p>
<p>Value</p>
</div>
</div>
<div className={variableStyles.variableList}>
{/* <div className={variableStyles.emptyVariableList}>
<div>
<p>No Environment Variables added</p>
</div>
</div> */}
{sampleData.map((data, key) => {
return (
<div className={variableStyles.variable} key={key}>
<p>{data.key}</p>
<p>{data.value}</p>
<DeleteIcon />
</div>
);
})}
</div>
</div>
</div>
<div className={variableStyles.variablesContent}>
<div
className={variableStyles.environmentVariablesContainer}
>
<div
className={variableStyles.environmentVariablesHeader}
>
<p>Volumes</p>
</div>
<div className={variableStyles.envVariablesHeader}>
<div>
<p>Name</p>
<p>Path</p>
<p>Size/Type</p>
<p>Access Mode</p>
<p>Storage Class</p>
</div>
</div>
<div className={variableStyles.variableList}>
<div className={variableStyles.emptyVariableList}>
<div>
<p>No volume added</p>
</div>
</div>
</div>
</div>
</div>
<div className={variableStyles.variablesContent}>
<div
className={variableStyles.environmentVariablesContainer}
>
<div
className={variableStyles.environmentVariablesHeader}
>
<p>Config maps</p>
</div>
<div className={variableStyles.variableList}>
<div className={variableStyles.emptyVariableList}>
<div>
<p>No config map added</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default AddServices;

View File

@@ -0,0 +1,219 @@
.contentContainer {
display: flex;
align-items: flex-start;
flex: 1 0 0;
align-self: stretch;
}
.fieldsContainerCreateNew {
display: flex;
padding-top: 36px;
flex-direction: column;
width: 550px;
align-items: flex-start;
gap: 36px;
background: #191a24;
height: calc(100vh - 175px);
overflow-y: scroll;
scrollbar-width: none;
}
.projectDetails {
display: flex;
padding: 0 36px;
flex-direction: column;
align-items: flex-start;
gap: 10px;
align-self: stretch;
}
.projectDetailsHeader {
display: flex;
padding-bottom: 24px;
align-items: flex-start;
gap: 17px;
align-self: stretch;
}
.projectDetailsHeader p {
color: #d2d3e1;
font-size: 20px;
font-style: normal;
font-weight: 500;
line-height: normal;
letter-spacing: 0.2px;
}
.fieldsCreateNew {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 16px;
align-self: stretch;
}
.resource {
display: flex;
padding: 0 36px;
flex-direction: column;
align-items: flex-start;
align-self: stretch;
}
.resourceFields {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 16px;
align-self: stretch;
}
.fieldsCreateNew > div,
.resourceFields > div {
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
align-self: stretch;
}
.fieldsCreateNew > div > div,
.resourceFields > div > div {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
gap: 12px;
flex: 1 0 0;
}
.fieldsCreateNew > div > div p,
.resourceFields > div > div p {
color: #d2d3e1;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
letter-spacing: 0.16px;
}
.fieldsCreateNew > div > div p > span,
.resourceFields > div > div p > span {
color: #85869b;
}
.fieldsCreateNew > div > div select,
.resourceFields > div > div select {
display: flex;
padding: 12px;
flex-direction: column;
align-items: flex-start;
gap: 10px;
align-self: stretch;
border-radius: 4px;
border: 1px solid #4b4f6d;
background-color: transparent;
color: white;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
letter-spacing: 0.16px;
}
.repositoryForm {
display: flex;
padding: 12px;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
align-self: stretch;
border-radius: 4px;
border: 1px dashed #5980f1;
color: #5980f1;
text-align: center;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
letter-spacing: 0.16px;
cursor: pointer;
}
.repositoryForm:hover {
background: rgba(83, 89, 242, 0.1);
}
.additionalDetails {
display: flex;
padding: 16px;
flex-direction: column;
align-items: flex-start;
gap: 16px;
align-self: stretch;
}
.additionalDetails > div {
display: flex;
padding: 20px;
flex-direction: column;
align-items: flex-start;
gap: 10px;
align-self: stretch;
border-radius: 6px;
background: #1d1e2a;
}
.additionalDetails > div > div {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 16px;
align-self: stretch;
}
.additionalDetailsHeader {
display: flex;
padding-bottom: 24px;
align-items: flex-start;
gap: 17px;
align-self: stretch;
}
.additionalDetailsHeader div {
display: flex;
justify-content: space-between;
align-items: center;
flex: 1 0 0;
}
.additionalDetailsHeader p {
color: #d2d3e1;
font-size: 20px;
font-style: normal;
font-weight: 500;
line-height: normal;
letter-spacing: 0.2px;
}
.additionalDetailsFields {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 32px;
align-self: stretch;
}
.additionalDetailsFields > div {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 16px;
align-self: stretch;
}
.additionalDetailsFields > div > div {
display: flex;
justify-content: center;
align-items: center;
gap: 16px;
align-self: stretch;
}
.additionalDetailsFields > div > div > div {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
gap: 12px;
flex: 1;
}
.additionalDetailsFields p {
color: #d2d3e1;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
letter-spacing: 0.16px;
}

View File

@@ -0,0 +1,253 @@
.variables {
display: flex;
flex-direction: column;
align-items: flex-start;
flex: 1 0 0;
align-self: stretch;
background: #161720;
}
.variablesHeader {
display: flex;
padding: 8px 14px 8px 8px;
align-items: center;
gap: 10px;
align-self: stretch;
background: #161720;
}
.variablesHeader > div {
display: flex;
justify-content: space-between;
align-items: center;
flex: 1 0 0;
}
.searchContainer > div {
display: flex;
width: 310px;
padding: 8px 12px;
align-items: center;
gap: 9px;
}
.searchInputGroup {
display: flex;
align-items: center;
gap: 9px;
}
.searchInputGroup input {
color: white;
font-family: Inter;
font-size: 18px;
font-style: normal;
font-weight: 400;
line-height: normal;
letter-spacing: -0.09px;
outline: none;
background-color: transparent;
border: none;
}
.searchInputGroup input::placeholder {
color: #85869b;
}
.variablesHeaderDropDown {
display: flex;
width: 40px;
height: 40px;
flex-direction: column;
align-items: flex-end;
position: relative;
gap: 6px;
}
.variableHeaderDropdownButton {
display: flex;
padding: 8px;
justify-content: center;
align-items: center;
gap: 12px;
border-radius: 6px;
cursor: pointer;
background: #5359f2;
border: 1px solid #5358f200;
}
.variableHeaderDropdownButton:hover {
border-radius: 6px;
border: 1px solid #5359f2;
background: linear-gradient(180deg, #5359f2 0%, #2e3288 100%);
}
.dropDownContainer {
display: flex;
padding: 8px;
flex-direction: column;
align-items: flex-start;
gap: 6px;
border-radius: 6px;
background: #2d3144;
box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.25);
animation-name: dropDownAnimation;
animation-duration: 200ms;
}
@keyframes dropDownAnimation {
0% {
opacity: 0;
transform: translateY(-10%);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.dropDownContainer > div {
display: flex;
padding: 8px 12px;
align-items: center;
gap: 10px;
align-self: stretch;
text-wrap: nowrap;
width: 100%;
}
.dropDownContainer > div:hover {
background: #3c4159;
}
.dropDownContainer > div > div {
display: flex;
justify-content: center;
align-items: center;
gap: 12px;
color: #acb0ff;
font-family: Inter;
font-size: 18px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
.variablesContentContainer {
display: flex;
padding: 8px;
align-items: flex-start;
flex: 1 0 0;
align-self: stretch;
}
.variablesContentContainer > div {
display: flex;
padding-bottom: 16px;
flex-direction: column;
align-items: flex-start;
gap: 8px;
height: calc(100vh - 242px);
overflow: auto;
flex: 1 0 0;
}
.variablesContent {
display: flex;
padding-bottom: auto;
flex-direction: column;
align-items: flex-start;
align-self: stretch;
border-radius: 4px;
background: #1d1e2a;
}
.variable {
display: flex;
padding: 8px 0;
align-items: center;
align-self: stretch;
border-bottom: 0.5px solid #2e3042;
width: 100%;
}
.variable p {
display: flex;
align-items: center;
flex: 1 0 0;
align-self: stretch;
color: #d2d3e1;
font-size: 15px;
font-style: normal;
font-weight: 400;
line-height: normal;
letter-spacing: 0.15px;
}
.environmentVariablesContainer {
display: flex;
min-height: 200px;
padding-bottom: auto;
flex-direction: column;
align-items: flex-start;
align-self: stretch;
}
.environmentVariablesHeader {
display: flex;
padding: 12px 16px;
align-items: flex-start;
gap: 17px;
align-self: stretch;
}
.environmentVariablesHeader p {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
gap: 5px;
flex: 1 0 0;
color: #fff;
font-family: Inter;
font-size: 18px;
font-style: normal;
font-weight: 500;
line-height: normal;
}
.envVariablesHeader {
display: flex;
flex-direction: column;
align-items: flex-start;
align-self: stretch;
}
.envVariablesHeader > div {
display: flex;
padding: 12px 16px;
align-items: flex-start;
align-self: stretch;
border-bottom: 1px solid #2c2e3f;
}
.envVariablesHeader > div p {
display: flex;
align-items: flex-start;
flex: 1 0 0;
color: #85869b;
font-family: Inter;
font-size: 15px;
font-style: normal;
font-weight: 500;
line-height: normal;
}
.variableList {
display: flex;
padding: 0 16px 16px 16px;
flex-direction: column;
align-items: center;
align-self: stretch;
}
.emptyVariableList {
display: flex;
padding: 24px 16px 0 16px;
flex-direction: column;
align-items: flex-start;
gap: 10px;
flex: 1 0 0;
}
.emptyVariableList > div {
display: flex;
justify-content: center;
align-items: center;
align-self: stretch;
}
.emptyVariableList > div > div {
display: flex;
justify-content: center;
align-items: flex-start;
flex: 1 0 0;
color: #85869b;
text-align: center;
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: normal;
}

View File

@@ -5,11 +5,12 @@ import TopHeader from "@/app/components/topHeader/TopHeader";
import styles from "./styles.module.css";
import variableStyles from "./variableStyles.module.css";
import TextField from "@/app/components/fields/textfield";
import AddVariableModal from "./variableModals/AddVariableModal/AddVariableModal";
import AddVolumeModal from "./variableModals/AddVolumes/AddVolumeModal";
import AddConfigMapModal from "./variableModals/AddConfigMap/AddConfigMapModal";
import AddVariableModal from "../variableModals/AddVariableModal/AddVariableModal";
import AddVolumeModal from "../variableModals/AddVolumes/AddVolumeModal";
import AddConfigMapModal from "../variableModals/AddConfigMap/AddConfigMapModal";
import DeleteIcon from "@/app/components/icons/delete";
import CustomCheckbox from "@/app/components/checkbox/CheckBox";
import SelectField from "@/app/components/select/SelectField";
const AddServices = () => {
const [triggerVariableDropDown, setTriggerVariableDropDown] = useState(false);
const [triggerAddVariable, setTriggerAddVariable] = useState(false);
@@ -78,15 +79,25 @@ const AddServices = () => {
<div>
<div>
<p>Ingress</p>
<select name="" id="">
<option value="">Select</option>
</select>
<SelectField
label="Select"
options={[
{ label: "Option", value: "option" },
{ label: "Option 1", value: "option 1" },
{ label: "Option 2", value: "option 2" },
]}
/>
</div>
<div>
<p>Ingress</p>
<select name="" id="">
<option value="">Select</option>
</select>
<SelectField
label="Select"
options={[
{ label: "Option", value: "option" },
{ label: "Option 1", value: "option 1" },
{ label: "Option 2", value: "option 2" },
]}
/>
</div>
</div>
</div>
@@ -131,13 +142,13 @@ const AddServices = () => {
<div>
<div>
<div>
<p>Name</p>
<p>Minimum pods</p>
<TextField placeHolder="Enter service name" />
<TextField placeHolder="1" />
</div>
<div>
<p>Version</p>
<TextField placeHolder="Services version" />
<p>Maximum pods</p>
<TextField placeHolder="1" />
</div>
</div>
</div>
@@ -157,17 +168,12 @@ const AddServices = () => {
<div>
<div>
<p>Readiness Path</p>
<input
type="text"
placeholder="Enter Readiness path"
/>
<TextField placeHolder="Enter Readiness path" />
</div>
<div>
<p>Readiness Port</p>
<input
type="text"
placeholder="Enter Readiness port"
/>
<TextField placeHolder="Enter Readiness port" />
</div>
</div>
</div>

View File

@@ -146,7 +146,7 @@
}
.additionalDetails {
display: flex;
padding: 20px;
padding: 16px;
flex-direction: column;
align-items: flex-start;
gap: 16px;
@@ -228,24 +228,3 @@
line-height: normal;
letter-spacing: 0.16px;
}
.additionalDetailsFields input {
display: flex;
padding: 12px;
flex-direction: column;
align-items: flex-start;
width: 100%;
gap: 10px;
align-self: stretch;
background-color: transparent;
border-radius: 4px;
border: 1px solid #4b4f6d;
color: white;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
letter-spacing: 0.16px;
}
.additionalDetailsFields input::placeholder {
color: #85869b;
}

View File

@@ -4,10 +4,15 @@ import globalStyle from "../../globalStyle.module.css";
import TopHeader from "@/app/components/topHeader/TopHeader";
import styles from "./styles.module.css";
import AddServicesModal from "./AddServicesModal/AddServicesModal";
import { useRouter, usePathname } from "next/navigation";
const AddProject = () => {
const [triggerAddServicesModal, setTriggerAddServicesModal] = useState(false);
const router = useRouter();
const pathName = usePathname();
const sampleData = [
{
id: 1,
name: "accounting-service",
version: "v1",
health: {
@@ -24,6 +29,7 @@ const AddProject = () => {
ports: "3000:3000, 50054:50054",
},
{
id: 2,
name: "accounting-service",
version: "v1",
health: {
@@ -40,6 +46,7 @@ const AddProject = () => {
ports: "3000:3000, 50054:50054",
},
{
id: 3,
name: "accounting-service",
version: "v1",
health: {
@@ -56,70 +63,7 @@ const AddProject = () => {
ports: "3000:3000, 50054:50054",
},
{
name: "accounting-service",
version: "v1",
health: {
overall: "Healthy",
liveness: "Unreachable",
readiness: "Ready",
},
status: {
deployment: "Healthy",
replicas: "1/1",
},
image: "xuru.isaachybrid.com/698d24e36c2855a6f0d8cf9b/accounting-service",
ingress: "",
ports: "3000:3000, 50054:50054",
},
{
name: "accounting-service",
version: "v1",
health: {
overall: "Healthy",
liveness: "Unreachable",
readiness: "Ready",
},
status: {
deployment: "Healthy",
replicas: "1/1",
},
image: "xuru.isaachybrid.com/698d24e36c2855a6f0d8cf9b/accounting-service",
ingress: "",
ports: "3000:3000, 50054:50054",
},
{
name: "accounting-service",
version: "v1",
health: {
overall: "Healthy",
liveness: "Unreachable",
readiness: "Ready",
},
status: {
deployment: "Healthy",
replicas: "1/1",
},
image: "xuru.isaachybrid.com/698d24e36c2855a6f0d8cf9b/accounting-service",
ingress: "",
ports: "3000:3000, 50054:50054",
},
{
name: "accounting-service",
version: "v1",
health: {
overall: "Healthy",
liveness: "Unreachable",
readiness: "Ready",
},
status: {
deployment: "Healthy",
replicas: "1/1",
},
image: "xuru.isaachybrid.com/698d24e36c2855a6f0d8cf9b/accounting-service",
ingress: "",
ports: "3000:3000, 50054:50054",
},
{
id: 4,
name: "accounting-service",
version: "v1",
health: {
@@ -173,7 +117,12 @@ const AddProject = () => {
<tbody>
{sampleData.map((services, index) => {
return (
<tr key={index}>
<tr
key={index}
onClick={() =>
router.push(`${pathName}/${services.id}`)
}
>
<td>{services.name}</td>
<td style={{ textAlign: "center" }}>
{services.version}

View File

@@ -5,12 +5,11 @@ import TextField from "@/app/components/fields/textfield";
import AddIcon from "@/app/components/icons/add";
import PrimaryButton from "@/app/components/buttons/primarybutton/PrimaryButton";
const AddConfigMapModal = (props) => {
const [isGeneric, setIsGeneric] = useState(true);
return (
<div className={styles.container}>
<div className={styles.modal}>
<div className={styles.header}>
<p>Volumes</p>
<p>Config Maps</p>
<CloseIcon onClick={() => props.setTriggerAddConfigMap(false)} />
</div>
<div className={styles.contentContainer}>

View File

@@ -174,6 +174,41 @@
line-height: normal;
letter-spacing: 0.16px;
}
.verticalInput textarea {
display: flex;
height: 120px;
padding: 12px;
width: 100%;
flex-direction: column;
align-items: flex-start;
background-color: transparent;
gap: 10px;
align-self: stretch;
border-radius: 4px;
border: 1px solid #4b4f6d;
resize: none;
color: #85869b;
font-size: 16px;
font-family: inter;
font-style: normal;
font-weight: 400;
outline: none;
line-height: normal;
letter-spacing: 0.16px;
}
.verticalInput textarea:focus {
border-radius: 6px;
border: 1px solid #959aff;
background: rgba(75, 79, 109, 0.25);
}
.verticalInput textarea:focus::placeholder {
color: #4b4f6d;
font-family: Inter;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
.radioButtonsContainer {
display: flex;
align-items: flex-start;

View File

@@ -4,8 +4,8 @@ import CloseIcon from "@/app/components/icons/close";
import TextField from "@/app/components/fields/textfield";
import AddIcon from "@/app/components/icons/add";
import PrimaryButton from "@/app/components/buttons/primarybutton/PrimaryButton";
import SelectField from "@/app/components/select/SelectField";
const AddVariableModal = (props) => {
const [isGeneric, setIsGeneric] = useState(true);
return (
<div className={styles.container}>
<div className={styles.modal}>
@@ -73,11 +73,25 @@ const AddVariableModal = (props) => {
<div>
<div>
<p>Protocol</p>
<TextField placeHolder="MongoDB" />
<SelectField
label="Select"
options={[
{ label: "Option", value: "option" },
{ label: "Option 1", value: "option 1" },
{ label: "Option 2", value: "option 2" },
]}
/>
</div>
<div>
<p>Service</p>
<TextField placeHolder="Select a service" />
<SelectField
label="Select"
options={[
{ label: "Option", value: "option" },
{ label: "Option 1", value: "option 1" },
{ label: "Option 2", value: "option 2" },
]}
/>
</div>
</div>
</div>

View File

@@ -170,9 +170,23 @@
font-family: inter;
font-style: normal;
font-weight: 400;
outline: none;
line-height: normal;
letter-spacing: 0.16px;
}
.verticalInput textarea:focus {
border-radius: 6px;
border: 1px solid #959aff;
background: rgba(75, 79, 109, 0.25);
}
.verticalInput textarea:focus::placeholder {
color: #4b4f6d;
font-family: Inter;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
.authenticationContainer {
display: flex;
padding: 12px 12px 32px 12px;

View File

@@ -5,7 +5,6 @@ import TextField from "@/app/components/fields/textfield";
import AddIcon from "@/app/components/icons/add";
import PrimaryButton from "@/app/components/buttons/primarybutton/PrimaryButton";
const AddVolumeModal = (props) => {
const [isGeneric, setIsGeneric] = useState(true);
return (
<div className={styles.container}>
<div className={styles.modal}>

View File

@@ -173,6 +173,7 @@
line-height: normal;
letter-spacing: 0.16px;
}
.authenticationContainer {
display: flex;
padding: 12px 12px 32px 12px;