Merge branch 'DEVELOPMENT' of https://gitea.internship.project-moonshot.com/Laux/Frontend-Internal-Developer-Platform into DEVELOPMENT
This commit is contained in:
42
frontend/src/app/components/checkbox/CheckBox.jsx
Normal file
42
frontend/src/app/components/checkbox/CheckBox.jsx
Normal file
@@ -0,0 +1,42 @@
|
||||
"use client";
|
||||
import { useState } from "react";
|
||||
import CheckIcon from "../icons/check";
|
||||
import styles from "./styles.module.css";
|
||||
import CloseIcon from "../icons/close";
|
||||
import CheckedIcon from "../icons/switchIcons/checked";
|
||||
import UnCheckedIcon from "../icons/switchIcons/unchecked";
|
||||
|
||||
const CustomCheckbox = ({ checked, onChange, id }) => {
|
||||
const [isChecked, setIsChecked] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<input
|
||||
type="checkbox"
|
||||
id={id}
|
||||
className={styles.check}
|
||||
checked={checked}
|
||||
onChange={() => {
|
||||
setIsChecked(!isChecked);
|
||||
onChange;
|
||||
}}
|
||||
/>
|
||||
|
||||
<label htmlFor={id} className={styles.switch}>
|
||||
<span className={styles.knob}>
|
||||
{isChecked ? (
|
||||
<CheckedIcon
|
||||
width={16}
|
||||
height={16}
|
||||
color="#4F378A"
|
||||
viewBox="0 0 20 20"
|
||||
/>
|
||||
) : (
|
||||
<UnCheckedIcon width={16} height={16} color="#fff" />
|
||||
)}
|
||||
</span>
|
||||
</label>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomCheckbox;
|
||||
46
frontend/src/app/components/checkbox/styles.module.css
Normal file
46
frontend/src/app/components/checkbox/styles.module.css
Normal file
@@ -0,0 +1,46 @@
|
||||
.switch {
|
||||
display: flex;
|
||||
width: 53px;
|
||||
|
||||
height: 33px;
|
||||
align-items: center;
|
||||
background-color: white;
|
||||
cursor: pointer;
|
||||
padding: 0 2px;
|
||||
border-radius: 150px;
|
||||
position: relative;
|
||||
border: 2px solid #6d6d6d;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.check {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* The knob (replaces ::before) */
|
||||
.knob {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
background-color: #6d6d6d;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
transition: all 0.15s ease-in-out;
|
||||
}
|
||||
.knob:hover {
|
||||
box-shadow: 0 0 0px 5px #33333327;
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.check:checked + .switch .knob {
|
||||
transform: translateX(78%);
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
/* Optional background change */
|
||||
.check:checked + .switch {
|
||||
background-color: #8187ff;
|
||||
border: 2px solid #8187ff;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
28
frontend/src/app/components/icons/arrowDown.jsx
Normal file
28
frontend/src/app/components/icons/arrowDown.jsx
Normal 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;
|
||||
30
frontend/src/app/components/icons/switchIcons/checked.jsx
Normal file
30
frontend/src/app/components/icons/switchIcons/checked.jsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import React from "react";
|
||||
|
||||
const CheckedIcon = ({
|
||||
width = 20,
|
||||
height = 20,
|
||||
color = "white",
|
||||
strokeWidth = 1.5,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 28 28"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M4.53125 10L8.4375 13.9062L16.25 6.09375"
|
||||
stroke={color}
|
||||
strokeWidth={strokeWidth}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default CheckedIcon;
|
||||
39
frontend/src/app/components/icons/switchIcons/unchecked.jsx
Normal file
39
frontend/src/app/components/icons/switchIcons/unchecked.jsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import React from "react";
|
||||
|
||||
const UnCheckedIcon = ({
|
||||
width = 20,
|
||||
height = 20,
|
||||
color = "white",
|
||||
strokeWidth = 1.5,
|
||||
|
||||
viewBox = "0 0 28 28",
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox={viewBox}
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M20.7077 7.29199L7.29102 20.7087"
|
||||
stroke={color}
|
||||
strokeWidth={strokeWidth}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M7.29102 7.29199L20.7077 20.7087"
|
||||
stroke={color}
|
||||
strokeWidth={strokeWidth}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default UnCheckedIcon;
|
||||
38
frontend/src/app/components/icons/warning.jsx
Normal file
38
frontend/src/app/components/icons/warning.jsx
Normal 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;
|
||||
71
frontend/src/app/components/select/SelectField.jsx
Normal file
71
frontend/src/app/components/select/SelectField.jsx
Normal 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;
|
||||
83
frontend/src/app/components/select/styles.module.css
Normal file
83
frontend/src/app/components/select/styles.module.css
Normal 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;
|
||||
}
|
||||
@@ -65,7 +65,7 @@ const TopHeader = (props) => {
|
||||
{props.state === "add" ? (
|
||||
<>
|
||||
<div className={styles.button}>
|
||||
<CheckIcon />
|
||||
<CheckIcon width={20} height={20} />
|
||||
<p>{props.buttonText}</p>
|
||||
</div>
|
||||
<div className={styles.cancelButton} onClick={() => router.back()}>
|
||||
|
||||
@@ -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%);
|
||||
|
||||
Reference in New Issue
Block a user