Merge pull request #331 from bluewave-labs/feat/textfield-refactor
Refactored textfield components into one
This commit is contained in:
34 files changed
+502
-1175
No files matched your search
@@ -0,0 +1,89 @@
|
||||
.field {
|
||||
min-width: 250px;
|
||||
}
|
||||
.field h3.MuiTypography-root,
|
||||
.field h5.MuiTypography-root,
|
||||
.field input,
|
||||
.field textarea,
|
||||
.field .input-error {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.field h3.MuiTypography-root,
|
||||
.field h5.MuiTypography-root,
|
||||
.field input,
|
||||
.field textarea {
|
||||
color: var(--env-var-color-5);
|
||||
}
|
||||
.field h3.MuiTypography-root {
|
||||
font-weight: 500;
|
||||
}
|
||||
.field h3.MuiTypography-root span.field-required {
|
||||
color: var(--env-var-color-19);
|
||||
margin-left: 2px;
|
||||
}
|
||||
.field h3.MuiTypography-root span.field-optional {
|
||||
opacity: 0.6;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.field h5.MuiTypography-root {
|
||||
position: relative;
|
||||
opacity: 0.8;
|
||||
padding-right: var(--env-var-spacing-1-minus);
|
||||
}
|
||||
.field .MuiInputBase-root:has(input) {
|
||||
height: 34px;
|
||||
}
|
||||
.field .MuiInputBase-root:has(.MuiInputAdornment-root) {
|
||||
padding-right: var(--env-var-spacing-1-minus);
|
||||
}
|
||||
.field .MuiInputBase-root:has(.copy.MuiInputAdornment-root > .MuiButtonBase-root) {
|
||||
padding-right: 0;
|
||||
}
|
||||
.field .MuiInputBase-root .copy.MuiInputAdornment-root .MuiButtonBase-root {
|
||||
padding: 0 var(--env-var-spacing-1-minus);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
border-radius: 0;
|
||||
height: 34px;
|
||||
}
|
||||
.field .MuiInputBase-root .copy.MuiInputAdornment-root .MuiButtonBase-root svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.field .MuiInputBase-root .MuiInputAdornment-root .MuiButtonBase-root:hover {
|
||||
border-color: var(--env-var-color-29);
|
||||
}
|
||||
.field input {
|
||||
height: 100%;
|
||||
padding: 0 var(--env-var-spacing-1-minus);
|
||||
}
|
||||
.field .MuiInputBase-root:has(textarea) {
|
||||
padding: var(--env-var-spacing-1-minus);
|
||||
}
|
||||
.field .MuiOutlinedInput-root fieldset {
|
||||
border-color: var(--env-var-color-29);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
.field:not(:has(.input-error))
|
||||
.MuiOutlinedInput-root:hover:not(:has(input:focus)):not(:has(textarea:focus))
|
||||
fieldset {
|
||||
border-color: var(--env-var-color-29);
|
||||
}
|
||||
.field .input-error {
|
||||
color: var(--env-var-color-24);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.field:has(.input-error) .MuiOutlinedInput-root fieldset {
|
||||
border-color: var(--env-var-color-19);
|
||||
}
|
||||
|
||||
.register-page .field .MuiOutlinedInput-root fieldset,
|
||||
.register-page .field input,
|
||||
.login-page .field .MuiOutlinedInput-root fieldset,
|
||||
.login-page .field input,
|
||||
.forgot-password-page .field .MuiOutlinedInput-root fieldset,
|
||||
.forgot-password-page .field input,
|
||||
.set-new-password-page .field .MuiOutlinedInput-root fieldset,
|
||||
.set-new-password-page .field input {
|
||||
border-radius: var(--env-var-radius-2);
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import {
|
||||
IconButton,
|
||||
InputAdornment,
|
||||
Stack,
|
||||
TextField,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import VisibilityOff from "@mui/icons-material/VisibilityOff";
|
||||
import Visibility from "@mui/icons-material/Visibility";
|
||||
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
||||
import Button from "../../Button";
|
||||
import "./index.css";
|
||||
import { useState } from "react";
|
||||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {string} [props.type] - Type of input field (e.g., 'text', 'password').
|
||||
* @param {string} props.id - ID of the input field.
|
||||
* @param {string} [props.label] - Label for the input field.
|
||||
* @param {boolean} [props.isRequired] - Indicates if the field is required, will display a red asterisk.
|
||||
* @param {boolean} [props.isOptional] - Indicates if the field is optional, will display optional text.
|
||||
* @param {boolean} [props.hasCopy] - Indicates if the field supports copying.
|
||||
* @param {string} [props.autoComplete] - Autocomplete value for the input field.
|
||||
* @param {string} [props.placeholder] - Placeholder text for the input field.
|
||||
* @param {string} props.value - Value of the input field.
|
||||
* @param {function} props.onChange - Function called on input change.
|
||||
* @param {string} [props.error] - Error message to display for the input field.
|
||||
* @param {boolean} [props.disabled] - Indicates if the input field is disabled.
|
||||
*/
|
||||
|
||||
const Field = ({
|
||||
type = "text",
|
||||
id,
|
||||
label,
|
||||
isRequired,
|
||||
isOptional,
|
||||
hasCopy,
|
||||
autoComplete,
|
||||
placeholder,
|
||||
value,
|
||||
onChange,
|
||||
error,
|
||||
disabled,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
// TODO - are we using this feature anywhere ?
|
||||
const [copy, setCopy] = useState(false);
|
||||
const handleCopy = () => {
|
||||
setCopy(true);
|
||||
setTimeout(() => setCopy(false), 1000);
|
||||
};
|
||||
|
||||
const [isVisible, setVisible] = useState(false);
|
||||
|
||||
return (
|
||||
<Stack gap={theme.gap.xs} className={`field field-${type}`}>
|
||||
{label && (
|
||||
<Typography component="h3">
|
||||
{label}
|
||||
{isRequired ? <span className="field-required">*</span> : ""}
|
||||
{isOptional ? <span className="field-optional">(optional)</span> : ""}
|
||||
</Typography>
|
||||
)}
|
||||
<TextField
|
||||
type={type === "password" ? (isVisible ? "text" : type) : type}
|
||||
id={id}
|
||||
autoComplete={autoComplete}
|
||||
placeholder={placeholder}
|
||||
multiline={type === "description"}
|
||||
rows={type === "description" ? 4 : 1}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
disabled={disabled}
|
||||
InputProps={{
|
||||
startAdornment: type === "url" && (
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
height="100%"
|
||||
sx={{
|
||||
borderRight: `solid 1px ${theme.palette.section.borderColor}`,
|
||||
}}
|
||||
>
|
||||
<Typography component="h5">https://</Typography>
|
||||
</Stack>
|
||||
),
|
||||
endAdornment:
|
||||
type === "password" ? (
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
aria-label="toggle password visibility"
|
||||
onClick={() => setVisible((show) => !show)}
|
||||
tabIndex={-1}
|
||||
sx={{
|
||||
color: theme.palette.section.borderColor,
|
||||
padding: `calc(${theme.gap.xs} / 2)`,
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
"& .MuiTouchRipple-root": {
|
||||
pointerEvents: "none",
|
||||
display: "none",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{!isVisible ? <VisibilityOff /> : <Visibility />}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
) : (
|
||||
hasCopy && (
|
||||
<InputAdornment className="copy" position="end">
|
||||
<Button
|
||||
level="tertiary"
|
||||
label={copy ? "Copied" : "Copy"}
|
||||
img={<ContentCopyIcon />}
|
||||
onClick={handleCopy}
|
||||
sx={{
|
||||
borderLeft: `solid 1px ${theme.palette.section.borderColor}`,
|
||||
lineHeight: 0,
|
||||
"& .MuiTouchRipple-root": {
|
||||
pointerEvents: "none",
|
||||
display: "none",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</InputAdornment>
|
||||
)
|
||||
),
|
||||
}}
|
||||
/>
|
||||
{error && (
|
||||
<Typography component="span" className="input-error" mt={theme.gap.xs}>
|
||||
{error}
|
||||
</Typography>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
Field.propTypes = {
|
||||
type: PropTypes.oneOf(["text", "password", "url", "email", "description"]),
|
||||
id: PropTypes.string.isRequired,
|
||||
label: PropTypes.string,
|
||||
isRequired: PropTypes.bool,
|
||||
isOptional: PropTypes.bool,
|
||||
hasCopy: PropTypes.bool,
|
||||
autoComplete: PropTypes.string,
|
||||
placeholder: PropTypes.string,
|
||||
value: PropTypes.string.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
error: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Field;
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -3,7 +3,7 @@ import React, { useState } from "react";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { Box, Divider, Stack, Typography } from "@mui/material";
|
||||
import ButtonSpinner from "../../ButtonSpinner";
|
||||
import PasswordTextField from "../../TextFields/Password/PasswordTextField";
|
||||
import Field from "../../Inputs/Field";
|
||||
import { editPasswordValidation } from "../../../Validation/validation";
|
||||
import Alert from "../../Alert";
|
||||
import { update } from "../../../Features/Auth/authSlice";
|
||||
@@ -35,7 +35,6 @@ const PasswordPanel = () => {
|
||||
confirm: "",
|
||||
});
|
||||
const [errors, setErrors] = useState({});
|
||||
const [showPassword, setShowPassword] = useState(false); // password visibility
|
||||
|
||||
const handleChange = (event) => {
|
||||
const { value, id } = event.target;
|
||||
@@ -120,76 +119,43 @@ const PasswordPanel = () => {
|
||||
<Stack>
|
||||
<Typography component="h1">Current password</Typography>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<PasswordTextField
|
||||
id="edit-current-password"
|
||||
label={null}
|
||||
placeholder="Enter your current password"
|
||||
autoComplete="current-password"
|
||||
visibility={showPassword}
|
||||
setVisibility={setShowPassword}
|
||||
value={localData.password}
|
||||
onChange={handleChange}
|
||||
error={errors[idToName["edit-current-password"]] ? true : false}
|
||||
/>
|
||||
{errors[idToName["edit-current-password"]] ? (
|
||||
<Typography component="p" className="input-error">
|
||||
{errors[idToName["edit-current-password"]]}
|
||||
</Typography>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Stack>
|
||||
<Field
|
||||
type="password"
|
||||
id="edit-current-password"
|
||||
placeholder="Enter your current password"
|
||||
autoComplete="current-password"
|
||||
value={localData.password}
|
||||
onChange={handleChange}
|
||||
error={errors[idToName["edit-current-password"]]}
|
||||
/>
|
||||
</div>
|
||||
<div className="edit-password-form__wrapper">
|
||||
<Stack>
|
||||
<Typography component="h1">New password</Typography>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<PasswordTextField
|
||||
id="edit-new-password"
|
||||
label={null}
|
||||
placeholder="Enter your new password"
|
||||
autoComplete="new-password"
|
||||
visibility={showPassword}
|
||||
setVisibility={setShowPassword}
|
||||
value={localData.newPassword}
|
||||
onChange={handleChange}
|
||||
error={errors[idToName["edit-new-password"]] ? true : false}
|
||||
/>
|
||||
{errors[idToName["edit-new-password"]] ? (
|
||||
<Typography component="p" className="input-error">
|
||||
{errors[idToName["edit-new-password"]]}
|
||||
</Typography>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Stack>
|
||||
<Field
|
||||
type="password"
|
||||
id="edit-new-password"
|
||||
placeholder="Enter your new password"
|
||||
autoComplete="new-password"
|
||||
value={localData.newPassword}
|
||||
onChange={handleChange}
|
||||
error={errors[idToName["edit-new-password"]]}
|
||||
/>
|
||||
</div>
|
||||
<div className="edit-password-form__wrapper">
|
||||
<Stack>
|
||||
<Typography component="h1">Confirm new password</Typography>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<PasswordTextField
|
||||
id="edit-confirm-password"
|
||||
label={null}
|
||||
placeholder="Reenter your new password"
|
||||
autoComplete="new-password"
|
||||
visibility={showPassword}
|
||||
setVisibility={setShowPassword}
|
||||
value={localData.confirm}
|
||||
onChange={handleChange}
|
||||
error={errors[idToName["edit-confirm-password"]] ? true : false}
|
||||
/>
|
||||
{errors[idToName["edit-confirm-password"]] ? (
|
||||
<Typography component="p" className="input-error">
|
||||
{errors[idToName["edit-confirm-password"]]}
|
||||
</Typography>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Stack>
|
||||
<Field
|
||||
type="password"
|
||||
id="edit-confirm-password"
|
||||
placeholder="Reenter your new password"
|
||||
autoComplete="new-password"
|
||||
value={localData.confirm}
|
||||
onChange={handleChange}
|
||||
error={errors[idToName["edit-confirm-password"]]}
|
||||
/>
|
||||
</div>
|
||||
<div className="edit-password-form__wrapper">
|
||||
<Stack></Stack>
|
||||
|
||||
@@ -4,9 +4,9 @@ import TabPanel from "@mui/lab/TabPanel";
|
||||
import { Box, Divider, Modal, Stack, Typography } from "@mui/material";
|
||||
import ButtonSpinner from "../../ButtonSpinner";
|
||||
import Button from "../../Button";
|
||||
import EmailTextField from "../../TextFields/Email/EmailTextField";
|
||||
import StringTextField from "../../TextFields/Text/TextField";
|
||||
import Avatar from "../../Avatar";
|
||||
import Field from "../../Inputs/Field";
|
||||
import ImageField from "../../Inputs/Image";
|
||||
import {
|
||||
editProfileValidation,
|
||||
imageValidation,
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
deleteUser,
|
||||
update,
|
||||
} from "../../../Features/Auth/authSlice";
|
||||
import ImageField from "../../TextFields/Image";
|
||||
import ImageIcon from "@mui/icons-material/Image";
|
||||
import ProgressUpload from "../../ProgressBars";
|
||||
import { formatBytes } from "../../../Utils/fileUtils";
|
||||
@@ -219,47 +218,27 @@ const ProfilePanel = () => {
|
||||
<Stack>
|
||||
<Typography component="h1">First name</Typography>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<StringTextField
|
||||
id="edit-first-name"
|
||||
label={null}
|
||||
value={localData.firstname}
|
||||
placeholder="Enter your first name"
|
||||
autoComplete="given-name"
|
||||
onChange={handleChange}
|
||||
error={errors[idToName["edit-first-name"]] ? true : false}
|
||||
/>
|
||||
{errors[idToName["edit-first-name"]] ? (
|
||||
<Typography component="p" className="input-error">
|
||||
{errors[idToName["edit-first-name"]]}
|
||||
</Typography>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Stack>
|
||||
<Field
|
||||
id="edit-first-name"
|
||||
value={localData.firstname}
|
||||
placeholder="Enter your first name"
|
||||
autoComplete="given-name"
|
||||
onChange={handleChange}
|
||||
error={errors[idToName["edit-first-name"]]}
|
||||
/>
|
||||
</div>
|
||||
<div className="edit-profile-form__wrapper">
|
||||
<Stack>
|
||||
<Typography component="h1">Last name</Typography>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<StringTextField
|
||||
id="edit-last-name"
|
||||
label={null}
|
||||
value={localData.lastname}
|
||||
placeholder="Enter your last name"
|
||||
autoComplete="family-name"
|
||||
onChange={handleChange}
|
||||
error={errors[idToName["edit-last-name"]] ? true : false}
|
||||
/>
|
||||
{errors[idToName["edit-last-name"]] ? (
|
||||
<Typography component="p" className="input-error">
|
||||
{errors[idToName["edit-last-name"]]}
|
||||
</Typography>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Stack>
|
||||
<Field
|
||||
id="edit-last-name"
|
||||
placeholder="Enter your last name"
|
||||
autoComplete="family-name"
|
||||
value={localData.lastname}
|
||||
onChange={handleChange}
|
||||
error={errors[idToName["edit-last-name"]]}
|
||||
/>
|
||||
</div>
|
||||
<div className="edit-profile-form__wrapper">
|
||||
<Stack>
|
||||
@@ -268,25 +247,15 @@ const ProfilePanel = () => {
|
||||
This is your current email address — it cannot be changed.
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<EmailTextField
|
||||
id="edit-email"
|
||||
label={null}
|
||||
value={user.email}
|
||||
placeholder="Enter your email"
|
||||
autoComplete="email"
|
||||
// onChange={handleChange}
|
||||
// error={errors[idToName["edit-email"]] ? true : false}
|
||||
disabled={true}
|
||||
/>
|
||||
{errors[idToName["edit-email"]] ? (
|
||||
<Typography component="p" className="input-error">
|
||||
{errors[idToName["edit-email"]]}
|
||||
</Typography>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Stack>
|
||||
<Field
|
||||
id="edit-email"
|
||||
value={user.email}
|
||||
placeholder="Enter your email"
|
||||
autoComplete="email"
|
||||
// onChange={handleChange}
|
||||
// error={errors[idToName["edit-email"]]}
|
||||
disabled={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="edit-profile-form__wrapper">
|
||||
<Stack>
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
import React from "react";
|
||||
import "./descriptionTextField.css";
|
||||
import { TextField } from "@mui/material";
|
||||
import PropTypes from "prop-types";
|
||||
import { useTheme } from "@mui/material";
|
||||
|
||||
/**
|
||||
* @component
|
||||
* @param {Object} props
|
||||
* @param {function} props.onChange - The function to call when the text field changes (optional)
|
||||
* @param {string} props.hintText - The hint text displayed within the text field (required)
|
||||
* @param {boolean} props.hasError - A flag indicating if the text field has an error (required)
|
||||
* @returns {JSX.Element} - Renders the description text field component
|
||||
*/
|
||||
const DescriptionTextField = ({ onChange, hintText, hasError }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const fontLookup = {
|
||||
default: theme.font.default.font,
|
||||
};
|
||||
|
||||
const fontFamily = fontLookup["default"];
|
||||
|
||||
return (
|
||||
<div
|
||||
className="description-field-holder"
|
||||
style={{ fontFamily: fontFamily }}
|
||||
>
|
||||
<div className="text-field-title">Description</div>
|
||||
<TextField
|
||||
onChange={onChange}
|
||||
id="description-field-area"
|
||||
error={hasError}
|
||||
className="description-field-area"
|
||||
multiline
|
||||
rows={4}
|
||||
placeholder="Enter a description..."
|
||||
helperText={hintText}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
DescriptionTextField.propTypes = {
|
||||
hintText: PropTypes.string.isRequired,
|
||||
hasError: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export default DescriptionTextField;
|
||||
@@ -1,77 +0,0 @@
|
||||
:root {
|
||||
--env-var-color-1: #101828;
|
||||
--env-var-color-2: #475467;
|
||||
--env-var-color-3: #1570ef;
|
||||
|
||||
--env-var-color-4: #d0d5dd;
|
||||
--env-var-color-5: #344054;
|
||||
--env-var-color-6: #eaecf0;
|
||||
--env-var-color-7: #7f56d9;
|
||||
--env-var-color-8: #fff;
|
||||
--env-var-color-9: #f2f2f2;
|
||||
--env-var-color-10: #175cd3;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-1: 100vw;
|
||||
--env-var-width-2: 360px;
|
||||
|
||||
--env-var-height-1: 100vh;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
--env-var-default-1: 24px;
|
||||
--env-var-default-2: 40px;
|
||||
}
|
||||
|
||||
.description-field-holder {
|
||||
margin: 10px 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.text-field-title {
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.description-field-area {
|
||||
min-width: 320px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.description-field-label {
|
||||
margin-top: 10px;
|
||||
font-size: var(--env-var-font-size-small);
|
||||
}
|
||||
|
||||
.with-error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
#description-field-area-helper-text {
|
||||
margin-left: 0;
|
||||
margin-top: 10px;
|
||||
font-size: var(--env-var-font-size-small);
|
||||
}
|
||||
|
||||
#description-field-area {
|
||||
min-width: 320px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import "./emailTextField.css";
|
||||
import { InputAdornment, TextField } from "@mui/material";
|
||||
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
|
||||
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
|
||||
import { useTheme } from "@mui/material";
|
||||
|
||||
/**
|
||||
* `EmailTextField` is a functional React component that renders a text field for email input.
|
||||
*
|
||||
* @component
|
||||
* @param {Object} props - The properties that define the `EmailTextField` component.
|
||||
* @param {function} props.onChange - The function to call when the text field changes.
|
||||
* @param {string} props.id - The id of the text field.
|
||||
* @param {string} [props.label="Email"] - The label of the text field.
|
||||
* @param {string} props.value - The value of the text field.
|
||||
* @param {string} props.variant - The variant of the text field.
|
||||
* @param {string} props.placeholder - The placeholder of the text field.
|
||||
* @param {React.Element} props.icon - The icon to be displayed in the text field.
|
||||
* @param {string} props.helperText - The helper text to be displayed below the text field.
|
||||
* @param {boolean} props.error - If true, the text field will indicate an error state.
|
||||
* @param {boolean} props.disabled - If true, the text field will be disabled and cannot be interacted with.
|
||||
*
|
||||
* @example
|
||||
* // To use this component, import it and use it in your JSX like this:
|
||||
* <EmailTextField id="email" variant="outlined" placeholder="Enter your email" />
|
||||
*
|
||||
* @returns {React.Element} The `EmailTextField` component with a text field for email input.
|
||||
*/
|
||||
|
||||
const EmailTextField = ({
|
||||
onChange,
|
||||
id,
|
||||
label = "Email",
|
||||
value = undefined,
|
||||
variant,
|
||||
placeholder,
|
||||
autoComplete,
|
||||
icon,
|
||||
helperText,
|
||||
error,
|
||||
disabled
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const fontLookup = {
|
||||
default: theme.font.default.font,
|
||||
};
|
||||
|
||||
const fontFamily = fontLookup["default"];
|
||||
|
||||
const [showIcon, setShowIcon] = useState(false);
|
||||
|
||||
const handleMouseEnter = () => setShowIcon(true);
|
||||
const handleMouseLeave = () => setShowIcon(false);
|
||||
|
||||
return (
|
||||
<div style={{ fontFamily: fontFamily }}>
|
||||
<div className="email-text-field-title">{label}</div>
|
||||
<div className="email-text-field">
|
||||
<TextField
|
||||
onChange={onChange}
|
||||
error={error}
|
||||
className="email-text-field-input"
|
||||
id={id}
|
||||
value={value}
|
||||
variant={variant}
|
||||
placeholder={placeholder}
|
||||
autoComplete={autoComplete}
|
||||
disabled={disabled}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<div className="icon-holder">
|
||||
{error && showIcon && (
|
||||
<ErrorOutlineIcon
|
||||
className="text-field-icon"
|
||||
style={{ fill: "red", width: "16px", height: "16px" }}
|
||||
/>
|
||||
)}
|
||||
{error && !showIcon && (
|
||||
<ErrorOutlineIcon
|
||||
className="text-field-icon"
|
||||
style={{ fill: "red", width: "16px", height: "16px" }}
|
||||
/>
|
||||
)}
|
||||
{!error && showIcon && !disabled && (
|
||||
<HelpOutlineIcon
|
||||
className="text-field-icon"
|
||||
style={{ width: "16px", height: "16px" }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
helperText={helperText}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmailTextField;
|
||||
@@ -1,77 +0,0 @@
|
||||
:root {
|
||||
--env-var-color-1: #101828;
|
||||
--env-var-color-2: #475467;
|
||||
--env-var-color-3: #1570ef;
|
||||
|
||||
--env-var-color-4: #d0d5dd;
|
||||
--env-var-color-5: #344054;
|
||||
--env-var-color-6: #eaecf0;
|
||||
--env-var-color-7: #7f56d9;
|
||||
--env-var-color-8: #fff;
|
||||
--env-var-color-9: #f2f2f2;
|
||||
--env-var-color-10: #175cd3;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-1: 100vw;
|
||||
--env-var-width-2: 360px;
|
||||
|
||||
--env-var-height-1: 100vh;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
--env-var-default-1: 24px;
|
||||
--env-var-default-2: 40px;
|
||||
}
|
||||
|
||||
.email-text-field {
|
||||
position: relative;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#outlined-basic {
|
||||
width: 320px;
|
||||
height: 14px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.email-text-field-title {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.email-text-field-input {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
|
||||
#outlined-basic-helper-text {
|
||||
margin-left: 0;
|
||||
margin-top: 10px;
|
||||
font-size: var(--env-var-font-size-small);
|
||||
}
|
||||
|
||||
.text-field-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.icon-holder {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import "./flexibileTextField.css";
|
||||
import { useTheme } from "@emotion/react";
|
||||
|
||||
/**
|
||||
* @param {Object} props - The component props.
|
||||
* @param {string} props.id - The ID of the input field.
|
||||
* @param {string} props.title - The title or label for the input field.
|
||||
* @param {string} props.type - The type of the input field (e.g., 'text', 'password').
|
||||
* @param {string} props.placeholder - The placeholder text for the input field.
|
||||
* @param {string} props.value - The current value of the input field.
|
||||
* @param {function} props.onChange - The function to call when the input field value changes.
|
||||
* @param {string} [props.error] - Optional. Error message to display if there's an error with the input.
|
||||
* @returns {JSX.Element} JSX Element representing the flexible text input field.
|
||||
*/
|
||||
|
||||
const FlexibileTextField = ({
|
||||
id,
|
||||
title,
|
||||
type,
|
||||
placeholder,
|
||||
value,
|
||||
onChange,
|
||||
error,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<Stack className="flexible-textfield" gap={theme.gap.small}>
|
||||
<Typography component="h2">{title}</Typography>
|
||||
<input
|
||||
id={id}
|
||||
type={type}
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
{error ? (
|
||||
<Typography component="p" className="input-error">
|
||||
{error}
|
||||
</Typography>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
FlexibileTextField.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
type: PropTypes.string.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
onChange: PropTypes.func.isRequired,
|
||||
error: PropTypes.string,
|
||||
};
|
||||
|
||||
export default FlexibileTextField;
|
||||
@@ -1,30 +0,0 @@
|
||||
.flexible-textfield{
|
||||
position: relative;
|
||||
}
|
||||
.flexible-textfield h2.MuiTypography-root{
|
||||
color: var(--env-var-color-5);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 400;
|
||||
}
|
||||
.flexible-textfield h2.MuiTypography-root span{
|
||||
opacity: 0.6;
|
||||
}
|
||||
.flexible-textfield input {
|
||||
min-width: 300px;
|
||||
height: 34px;
|
||||
padding: 0 var(--env-var-spacing-1);
|
||||
border: 1px solid var(--env-var-color-4);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
.flexible-textfield p.MuiTypography-root.input-error {
|
||||
color: var(--env-var-color-24);
|
||||
opacity: 0.8;
|
||||
position: absolute;
|
||||
top: calc(100% + 5px);
|
||||
}
|
||||
.flexible-textfield:has(p.MuiTypography-root.input-error) input{
|
||||
border-color: var(--env-var-color-24);
|
||||
}
|
||||
.flexible-textfield input:focus {
|
||||
outline: none;
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
import "./passwordTextField.css";
|
||||
import React, { useState } from "react";
|
||||
import { IconButton, InputAdornment, TextField } from "@mui/material";
|
||||
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
|
||||
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
|
||||
import { useTheme } from "@mui/material";
|
||||
import VisibilityOff from "@mui/icons-material/VisibilityOff";
|
||||
import Visibility from "@mui/icons-material/Visibility";
|
||||
|
||||
/**
|
||||
* @component
|
||||
* @param {Object} props
|
||||
* @param {string} props.value - The current value of the text field
|
||||
* @param {function} props.onChange - The function to call when the text field changes (optional)
|
||||
* @param {string} props.id - Unique ID for the text field (optional)
|
||||
* @param {string} props.label - The label text displayed above the text field (optional)
|
||||
* @param {"standard" | "outlined" | "filled"} props.variant - The variant of the text field (e.g., "outlined") (optional)
|
||||
* @param {string} props.placeholder - The placeholder text displayed within the text field (optional)
|
||||
* @param {"error" | "help"} [props.icon] - The type of icon to display (error or help) (optional)
|
||||
* @param {string} props.helperText - The helper text displayed below the text field (optional)
|
||||
* @param {boolean} props.error - A flag indicating if the text field has an error (required)
|
||||
* @param {boolean} props.visibility - A flag indicating if the password visibility is toggled (optional)
|
||||
* @param {function} props.setVisibility - Function to toggle password visibility (optional)
|
||||
* @returns {JSX.Element} - Renders the password text field component with dynamic icon display
|
||||
*/
|
||||
const PasswordTextField = ({
|
||||
value,
|
||||
onChange,
|
||||
id,
|
||||
label = "Password",
|
||||
autoComplete,
|
||||
variant,
|
||||
placeholder,
|
||||
icon,
|
||||
helperText,
|
||||
error,
|
||||
visibility,
|
||||
setVisibility,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const fontLookup = {
|
||||
default: theme.font.default.font,
|
||||
};
|
||||
|
||||
const fontFamily = fontLookup["default"];
|
||||
|
||||
const [showIcon, setShowIcon] = useState(false);
|
||||
|
||||
const handleMouseEnter = () => setShowIcon(true);
|
||||
const handleMouseLeave = () => setShowIcon(false);
|
||||
|
||||
return (
|
||||
<div style={{ fontFamily: fontFamily }}>
|
||||
<div className="password-text-field-title">{label}</div>
|
||||
<div className="password-text-field">
|
||||
<TextField
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
type={visibility ? "text" : "password"}
|
||||
autoComplete={autoComplete}
|
||||
error={error}
|
||||
className="password-text-field-input"
|
||||
id={id}
|
||||
variant={variant}
|
||||
placeholder={placeholder}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
{visibility !== undefined ? (
|
||||
<IconButton
|
||||
aria-label="toggle password visibility"
|
||||
onClick={() => setVisibility((show) => !show)}
|
||||
tabIndex={-1}
|
||||
sx={{
|
||||
width: "30px",
|
||||
height: "30px",
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{!visibility ? <VisibilityOff /> : <Visibility />}
|
||||
</IconButton>
|
||||
) : (
|
||||
<div className="icon-holder">
|
||||
{error && showIcon && (
|
||||
<ErrorOutlineIcon
|
||||
className="text-field-icon"
|
||||
style={{ fill: "red", width: "16px", height: "16px" }}
|
||||
/>
|
||||
)}
|
||||
{error && !showIcon && (
|
||||
<ErrorOutlineIcon
|
||||
className="text-field-icon"
|
||||
style={{ fill: "red", width: "16px", height: "16px" }}
|
||||
/>
|
||||
)}
|
||||
{!error && showIcon && (
|
||||
<HelpOutlineIcon
|
||||
className="text-field-icon"
|
||||
style={{ width: "16px", height: "16px" }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
helperText={helperText}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PasswordTextField;
|
||||
@@ -1,73 +0,0 @@
|
||||
:root {
|
||||
--env-var-color-1: #101828;
|
||||
--env-var-color-2: #475467;
|
||||
--env-var-color-3: #1570ef;
|
||||
|
||||
--env-var-color-4: #d0d5dd;
|
||||
--env-var-color-5: #344054;
|
||||
--env-var-color-6: #eaecf0;
|
||||
--env-var-color-7: #7f56d9;
|
||||
--env-var-color-8: #fff;
|
||||
--env-var-color-9: #f2f2f2;
|
||||
--env-var-color-10: #175cd3;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-1: 100vw;
|
||||
--env-var-width-2: 360px;
|
||||
|
||||
--env-var-height-1: 100vh;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
--env-var-default-1: 24px;
|
||||
--env-var-default-2: 40px;
|
||||
}
|
||||
|
||||
.password-text-field {
|
||||
position: relative;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#outlined-basic {
|
||||
width: 320px;
|
||||
height: 14px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.password-text-field-title {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#outlined-basic-helper-text {
|
||||
margin-left: 0;
|
||||
margin-top: 10px;
|
||||
font-size: var(--env-var-font-size-small);
|
||||
}
|
||||
|
||||
.text-field-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.icon-holder {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
import "./textField.css";
|
||||
import React, { useState } from "react";
|
||||
import { InputAdornment, TextField } from "@mui/material";
|
||||
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
|
||||
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
|
||||
import { useTheme } from "@mui/material";
|
||||
|
||||
/**
|
||||
* @param {Object} props - The component props.
|
||||
* @param {function} props.onChange - The function to call when the text field changes.
|
||||
* @param {string} props.id - The ID of the text field.
|
||||
* @param {string} props.label - The label text for the text field.
|
||||
* @param {string} props.value - The value of the text field.
|
||||
* @param {string} props.variant - The variant of the text field.
|
||||
* @param {string} props.placeholder - The placeholder text for the text field.
|
||||
* @param {ReactNode} props.icon - The icon to display in the text field.
|
||||
* @param {string} props.helperText - The helper text for the text field.
|
||||
* @param {boolean} props.error - Whether the text field has an error.
|
||||
* @returns {JSX.Element} The rendered component.
|
||||
*/
|
||||
const StringTextField = ({
|
||||
onChange,
|
||||
autoComplete,
|
||||
id,
|
||||
label,
|
||||
value = undefined,
|
||||
variant,
|
||||
placeholder,
|
||||
icon,
|
||||
helperText,
|
||||
error,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const fontLookup = {
|
||||
default: theme.font.default.font,
|
||||
};
|
||||
|
||||
const fontFamily = fontLookup["default"];
|
||||
|
||||
const [showIcon, setShowIcon] = useState(false);
|
||||
|
||||
const handleMouseEnter = () => setShowIcon(true);
|
||||
const handleMouseLeave = () => setShowIcon(false);
|
||||
|
||||
return (
|
||||
<div style={{ fontFamily: fontFamily }}>
|
||||
<div className="email-text-field-title">{label}</div>
|
||||
<div className="email-text-field">
|
||||
<TextField
|
||||
onChange={onChange}
|
||||
error={error}
|
||||
className="email-text-field-input"
|
||||
id={id}
|
||||
variant={variant}
|
||||
value={value}
|
||||
placeholder={placeholder}
|
||||
autoComplete={autoComplete}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<div className="icon-holder">
|
||||
{error && showIcon && (
|
||||
<ErrorOutlineIcon
|
||||
className="text-field-icon"
|
||||
style={{ fill: "red", width: "16px", height: "16px" }}
|
||||
/>
|
||||
)}
|
||||
{error && !showIcon && (
|
||||
<ErrorOutlineIcon
|
||||
className="text-field-icon"
|
||||
style={{ fill: "red", width: "16px", height: "16px" }}
|
||||
/>
|
||||
)}
|
||||
{!error && showIcon && (
|
||||
<HelpOutlineIcon
|
||||
className="text-field-icon"
|
||||
style={{ width: "16px", height: "16px" }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
helperText={helperText}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default StringTextField;
|
||||
@@ -1,37 +0,0 @@
|
||||
:root {
|
||||
--env-var-color-1: #101828;
|
||||
--env-var-color-2: #475467;
|
||||
--env-var-color-3: #1570ef;
|
||||
|
||||
--env-var-color-4: #d0d5dd;
|
||||
--env-var-color-5: #344054;
|
||||
--env-var-color-6: #eaecf0;
|
||||
--env-var-color-7: #7f56d9;
|
||||
--env-var-color-8: #fff;
|
||||
--env-var-color-9: #f2f2f2;
|
||||
--env-var-color-10: #175cd3;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-1: 100vw;
|
||||
--env-var-width-2: 360px;
|
||||
|
||||
--env-var-height-1: 100vh;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
--env-var-default-1: 24px;
|
||||
--env-var-default-2: 40px;
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import "./websiteTextField.css";
|
||||
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
|
||||
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
||||
import { useTheme } from "@mui/material";
|
||||
|
||||
/**
|
||||
* @component
|
||||
* @param {Object} props
|
||||
* @param {boolean} [props.showHelp=true] - Controls the visibility of the help icon (defaults to true)
|
||||
* @param {boolean} [props.hasCopyButton=false] - Controls the visibility of the copy button (defaults to false)
|
||||
* @param {string} props.hintText - The hint text displayed below the text field (required)
|
||||
* @returns {JSX.Element} - Renders the website text field component with optional help and copy features
|
||||
*/
|
||||
const WebsiteTextField = ({
|
||||
showHelp = true,
|
||||
hasCopyButton = false,
|
||||
hintText,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const fontLookup = {
|
||||
default: theme.font.default.font,
|
||||
};
|
||||
|
||||
const fontFamily = fontLookup["default"];
|
||||
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const handleCopy = () => {
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 1000);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ fontFamily: fontFamily }}>
|
||||
<div className="website-textfield-title">Website</div>
|
||||
<div className="website-textfield">
|
||||
<label className="website-label">http://</label>
|
||||
<input
|
||||
type="url"
|
||||
name="website-url"
|
||||
id="website-url"
|
||||
className="website-url"
|
||||
/>
|
||||
{showHelp && (
|
||||
<div
|
||||
className={
|
||||
`website-icon-holder ` + !hasCopyButton
|
||||
? "with-no-copy-button"
|
||||
: ""
|
||||
}
|
||||
>
|
||||
<HelpOutlineIcon style={{ fill: "var(--icon-color)" }} />
|
||||
</div>
|
||||
)}
|
||||
{hasCopyButton && (
|
||||
<div className="copy-to-clipboard-button" onClick={handleCopy}>
|
||||
<ContentCopyIcon
|
||||
className="copy-icon"
|
||||
style={{ width: "20px", height: "20px" }}
|
||||
/>
|
||||
<span className="">{copied ? " Copied " : " Copy "}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<label className="website-textfield-hint">{hintText}</label>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default WebsiteTextField;
|
||||
@@ -1,111 +0,0 @@
|
||||
:root {
|
||||
--env-var-color-1: #101828;
|
||||
--env-var-color-2: #475467;
|
||||
--env-var-color-3: #1570ef;
|
||||
|
||||
--env-var-color-4: #d0d5dd;
|
||||
--env-var-color-5: #344054;
|
||||
--env-var-color-6: #eaecf0;
|
||||
--env-var-color-7: #7f56d9;
|
||||
--env-var-color-8: #fff;
|
||||
--env-var-color-9: #f2f2f2;
|
||||
--env-var-color-10: #175cd3;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-1: 100vw;
|
||||
--env-var-width-2: 360px;
|
||||
|
||||
--env-var-height-1: 100vh;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
--env-var-default-1: 24px;
|
||||
--env-var-default-2: 40px;
|
||||
}
|
||||
|
||||
.website-textfield-title {
|
||||
margin: 0 20px;
|
||||
margin-top: 30px;
|
||||
font-size: 13px;
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.website-textfield {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
margin: 10px 20px 5px;
|
||||
}
|
||||
|
||||
.website-textfield-hint {
|
||||
margin: 10px 20px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.website-label {
|
||||
padding: 6px 20px 6px 10px;
|
||||
border: solid 1px var(--env-var-color-4);
|
||||
border-right: none;
|
||||
border-radius: 4px 0 0 4px;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
|
||||
.website-url {
|
||||
width: 248px;
|
||||
height: 31.5px;
|
||||
padding: 0px 15px;
|
||||
border: solid 1px var(--env-var-color-4);
|
||||
}
|
||||
|
||||
.website-icon-holder {
|
||||
width: 40px;
|
||||
height: 33px;
|
||||
padding: 5px;
|
||||
border: solid 1px var(--env-var-color-4);
|
||||
border-left: none;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.copy-to-clipboard-button {
|
||||
padding: 5.5px 20px 6px 10px;
|
||||
border: solid 1px var(--env-var-color-4);
|
||||
border-left: none;
|
||||
border-radius: 0 8px 8px 0;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
color: var(--env-var-color-2);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.copy-icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.with-no-copy-button {
|
||||
display: none;
|
||||
}
|
||||
@@ -139,7 +139,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.account .MuiStack-root:has(p.MuiTypography-root.input-error) {
|
||||
.account .MuiStack-root:has(span.MuiTypography-root.input-error) {
|
||||
position: relative;
|
||||
}
|
||||
.account .text-field-icon {
|
||||
@@ -150,11 +150,9 @@
|
||||
height: 18px !important;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.account p.MuiTypography-root.input-error {
|
||||
color: var(--env-var-color-24);
|
||||
opacity: 0.8;
|
||||
.account span.MuiTypography-root.input-error {
|
||||
position: absolute;
|
||||
top: calc(100% + 5px);
|
||||
top: 100%;
|
||||
}
|
||||
.account .email-text-field,
|
||||
.account .password-text-field {
|
||||
|
||||
@@ -55,6 +55,13 @@
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
.create-monitor-form .MuiStack-root:has(span.MuiTypography-root.input-error) {
|
||||
position: relative;
|
||||
}
|
||||
.create-monitor-form span.MuiTypography-root.input-error {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
}
|
||||
|
||||
.monitors-gaps-medium {
|
||||
height: var(--env-var-spacing-2);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import "./index.css";
|
||||
import ConfigBox from "../../Components/ConfigBox";
|
||||
import FlexibileTextField from "../../Components/TextFields/Flexibile/FlexibileTextField";
|
||||
import React, { useState } from "react";
|
||||
import RadioButton from "../../Components/RadioButton";
|
||||
import CustomizableCheckBox from "../../Components/Checkbox/CustomizableCheckbox";
|
||||
@@ -12,6 +11,7 @@ import { createMonitor } from "../../Features/Monitors/monitorsSlice";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import WestRoundedIcon from "@mui/icons-material/WestRounded";
|
||||
import Field from "../../Components/Inputs/Field";
|
||||
|
||||
const CreateNewMonitor = () => {
|
||||
const MS_PER_MINUTE = 60000;
|
||||
@@ -86,6 +86,7 @@ const CreateNewMonitor = () => {
|
||||
//obj to submit
|
||||
let monitor = {
|
||||
...generalSettings,
|
||||
url: "https://" + generalSettings.url,
|
||||
...checks,
|
||||
};
|
||||
|
||||
@@ -162,25 +163,22 @@ const CreateNewMonitor = () => {
|
||||
}
|
||||
rightLayout={
|
||||
<Stack gap={theme.gap.xl}>
|
||||
<FlexibileTextField
|
||||
id="monitor-url"
|
||||
title="URL to monitor"
|
||||
<Field
|
||||
type="url"
|
||||
placeholder="https://google.com"
|
||||
id="monitor-url"
|
||||
label="URL to monitor"
|
||||
placeholder="google.com"
|
||||
value={generalSettings.url}
|
||||
onChange={(event) =>
|
||||
handleChange(event, "url", setGeneralSettings)
|
||||
}
|
||||
error={errors["url"]}
|
||||
/>
|
||||
<FlexibileTextField
|
||||
id="monitor-name"
|
||||
title={
|
||||
<>
|
||||
Friendly name <span>(optional)</span>
|
||||
</>
|
||||
}
|
||||
<Field
|
||||
type="text"
|
||||
id="monitor-name"
|
||||
label="Friendly name"
|
||||
isOptional={true}
|
||||
placeholder="Google"
|
||||
value={generalSettings.name}
|
||||
onChange={(event) =>
|
||||
|
||||
@@ -37,11 +37,11 @@ import { useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { getMonitors } from "../../Features/Monitors/monitorsSlice";
|
||||
import { getMonitorsByUserId } from "../../Features/Monitors/monitorsSlice";
|
||||
import ImageField from "../../Components/TextFields/Image";
|
||||
import ImageField from "../../Components/Inputs/Image";
|
||||
import ProgressUpload from "../../Components/ProgressBars";
|
||||
import Alert from "../../Components/Alert";
|
||||
import { createToast } from "../../Utils/toastUtils";
|
||||
import { ToastContainer } from "react-toastify";
|
||||
import Field from "../../Components/Inputs/Field";
|
||||
|
||||
const cols = [
|
||||
{
|
||||
@@ -203,6 +203,9 @@ const Demo = () => {
|
||||
setIsLoading(false);
|
||||
}, 4000);
|
||||
};
|
||||
|
||||
//fields
|
||||
const [visibility, setVisibility] = useState(false);
|
||||
return (
|
||||
<div>
|
||||
<div style={{ padding: "4rem", border: "1px solid black" }}>
|
||||
@@ -439,7 +442,7 @@ const Demo = () => {
|
||||
/>
|
||||
</Stack>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<Stack justifyContent="center" alignItems="center">
|
||||
<Stack direction="row" gap="10px" flexWrap="wrap">
|
||||
<Box width="500px">
|
||||
<Alert
|
||||
variant="info"
|
||||
@@ -447,20 +450,20 @@ const Demo = () => {
|
||||
body="Since you logged in via SSO, you cannot reset or modify your password."
|
||||
/>
|
||||
</Box>
|
||||
<Box width="500px" mt="5px">
|
||||
<Box width="500px">
|
||||
<Alert
|
||||
variant="warning"
|
||||
body="New password must contain at least 8 characters and must have at least one uppercase letter, one number and one symbol."
|
||||
/>
|
||||
</Box>
|
||||
<Box width="500px" mt="5px">
|
||||
<Box width="500px">
|
||||
<Alert
|
||||
variant="error"
|
||||
title="Error"
|
||||
body="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
|
||||
/>
|
||||
</Box>
|
||||
<Box width="500px" mt="5px">
|
||||
<Box width="500px">
|
||||
<Alert
|
||||
variant="info"
|
||||
title="We've just released a new feature"
|
||||
@@ -468,7 +471,7 @@ const Demo = () => {
|
||||
isToast={true}
|
||||
/>
|
||||
</Box>
|
||||
<Box width="500px" mt="5px">
|
||||
<Box width="500px">
|
||||
<Alert
|
||||
variant="info"
|
||||
body="Your password is incorrect."
|
||||
@@ -491,7 +494,28 @@ const Demo = () => {
|
||||
</Box>
|
||||
</Stack>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<ToastContainer />
|
||||
<Stack direction="row" justifyContent="center" gap="20px">
|
||||
<Field type="text" label="Name" placeholder="Enter a name" />
|
||||
<Field
|
||||
type="email"
|
||||
label="Email"
|
||||
isRequired={true}
|
||||
placeholder="name.surname@companyname.com"
|
||||
error="This is an error message."
|
||||
/>
|
||||
<Field
|
||||
type="password"
|
||||
label="Password"
|
||||
isRequired={true}
|
||||
placeholder="Create a password"
|
||||
/>
|
||||
<Field
|
||||
type="url"
|
||||
label="Website"
|
||||
placeholder="google.com"
|
||||
/>
|
||||
</Stack>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,13 +2,13 @@ import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPatt
|
||||
import "./index.css";
|
||||
import React from "react";
|
||||
import Logomark from "../../assets/Images/key-password.png";
|
||||
import EmailTextField from "../../Components/TextFields/Email/EmailTextField";
|
||||
import Button from "../../Components/Button";
|
||||
import LeftArrow from "../../assets/Images/arrow-left.png";
|
||||
import { useState, useEffect } from "react";
|
||||
import { recoveryValidation } from "../../Validation/validation";
|
||||
import axiosInstance from "../../Utils/axiosConfig";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Field from "../../Components/Inputs/Field";
|
||||
|
||||
const ForgotPassword = () => {
|
||||
const navigate = useNavigate();
|
||||
@@ -76,12 +76,14 @@ const ForgotPassword = () => {
|
||||
</div>
|
||||
<div className="forgot-password-v-gap-large"></div>
|
||||
<div className="forgot-password-body">
|
||||
<EmailTextField
|
||||
onChange={handleInput}
|
||||
error={errors.email !== undefined ? true : false}
|
||||
helperText={errors.email !== undefined ? errors.email : ""}
|
||||
placeholder="Enter your email"
|
||||
<Field
|
||||
type="email"
|
||||
id="forgot-password-email-input"
|
||||
label="Email"
|
||||
isRequired={true}
|
||||
placeholder="Enter your email"
|
||||
onChange={handleInput}
|
||||
error={errors.email}
|
||||
/>
|
||||
<div className="forgot-password-v-gap-medium"></div>
|
||||
<Button
|
||||
|
||||
@@ -39,17 +39,9 @@
|
||||
color: var(--env-var-color-1);
|
||||
}
|
||||
|
||||
#login-email-input {
|
||||
width: 308px;
|
||||
height: 1px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
|
||||
#login-password-input {
|
||||
width: 308px;
|
||||
height: 1px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
/* .login-form-inputs .field h3.MuiTypography-root{
|
||||
font-weight: 600;
|
||||
} */
|
||||
|
||||
.login-form-password-options {
|
||||
display: flex;
|
||||
|
||||
@@ -4,16 +4,15 @@ import { useNavigate } from "react-router-dom";
|
||||
import "./index.css";
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import Logomark from "../../assets/Images/Logomark.png";
|
||||
import EmailTextField from "../../Components/TextFields/Email/EmailTextField";
|
||||
import CheckBox from "../../Components/Checkbox/Checkbox";
|
||||
import Button from "../../Components/Button";
|
||||
import Google from "../../assets/Images/Google.png";
|
||||
import PasswordTextField from "../../Components/TextFields/Password/PasswordTextField";
|
||||
import axiosInstance from "../../Utils/axiosConfig";
|
||||
import { loginValidation } from "../../Validation/validation";
|
||||
import { login } from "../../Features/Auth/authSlice";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { createToast } from "../../Utils/toastUtils";
|
||||
import Field from "../../Components/Inputs/Field";
|
||||
|
||||
const Login = () => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -125,23 +124,26 @@ const Login = () => {
|
||||
<div className="login-form-heading">Log in to your account</div>
|
||||
</div>
|
||||
<div className="login-form-v3-spacing" />
|
||||
|
||||
<div className="login-form-inputs">
|
||||
<EmailTextField
|
||||
onChange={handleInput}
|
||||
error={errors.email ? true : false}
|
||||
helperText={errors.email ? errors.email : ""}
|
||||
<Field
|
||||
type="email"
|
||||
id="login-email-input"
|
||||
label="Email"
|
||||
placeholder="Enter your email"
|
||||
autoComplete="email"
|
||||
id="login-email-input"
|
||||
onChange={handleInput}
|
||||
error={errors.email}
|
||||
/>
|
||||
<div className="login-form-v2-spacing" />
|
||||
<PasswordTextField
|
||||
onChange={handleInput}
|
||||
error={errors.password ? true : false}
|
||||
helperText={errors.password ? errors.password : ""}
|
||||
placeholder="Password"
|
||||
autoComplete="current-password"
|
||||
<Field
|
||||
type="password"
|
||||
id="login-password-input"
|
||||
label="Password"
|
||||
placeholder="Enter your password"
|
||||
autoComplete="current-password"
|
||||
onChange={handleInput}
|
||||
error={errors.password}
|
||||
/>
|
||||
</div>
|
||||
<div className="login-form-v3-spacing" />
|
||||
|
||||
@@ -6,7 +6,7 @@ import { getMonitorsByUserId } from "../../Features/Monitors/monitorsSlice";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Button from "../../Components/Button";
|
||||
import ServerStatus from "../../Components/Charts/Servers/ServerStatus";
|
||||
import SearchTextField from "../../Components/TextFields/Search/SearchTextField";
|
||||
import SearchTextField from "../../Components/Inputs/Search/SearchTextField";
|
||||
import MonitorTable from "../../Components/MonitorTable";
|
||||
import { useTheme } from "@emotion/react";
|
||||
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import React from "react";
|
||||
import EmailTextField from "../../Components/TextFields/Email/EmailTextField";
|
||||
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
|
||||
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
|
||||
import WebsiteTextField from "../../Components/TextFields/Website/WebsiteTextField";
|
||||
import DescriptionTextField from "../../Components/TextFields/Description/DescriptionTextField";
|
||||
import PlayGroundCharts from "./PlayGround-Charts";
|
||||
import PlayGroundPopupModals from "./PlayGround-Popup-Modals";
|
||||
import PlayGroundTooltips from "./PlayGround-Tooltips";
|
||||
import Field from "../../Components/Inputs/Field";
|
||||
|
||||
// This Component is just for the development and test
|
||||
// purposes and just to see what my components look like while development
|
||||
@@ -15,49 +11,71 @@ function PlayGround() {
|
||||
return (
|
||||
<div>
|
||||
{/* Default state of Email Text Fields */}
|
||||
<EmailTextField
|
||||
error={false}
|
||||
placeholder="olivia@untitledui.com"
|
||||
id="outlined-basic"
|
||||
helperText="This is a hint text to help user."
|
||||
/>
|
||||
{/* Email Text Field when validation error occures */}
|
||||
<EmailTextField
|
||||
error={true}
|
||||
placeholder="olivia@untitledui.com"
|
||||
id="outlined-basic"
|
||||
icon={<ErrorOutlineIcon style={{ fill: "red" }} />}
|
||||
helperText="This is an error message"
|
||||
/>
|
||||
{/* Email Text Field while mouse hover */}
|
||||
<EmailTextField
|
||||
error={false}
|
||||
placeholder="olivia@untitledui.com"
|
||||
id="outlined-basic"
|
||||
icon={<HelpOutlineIcon />}
|
||||
helperText="This is a hint text to help user."
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "10px",
|
||||
maxWidth: "400px",
|
||||
padding: "10px",
|
||||
}}
|
||||
>
|
||||
<Field
|
||||
type="email"
|
||||
id="outlined-basic"
|
||||
label="Email"
|
||||
placeholder="olivia@untitledui.com"
|
||||
/>
|
||||
{/* Email Text Field when validation error occures */}
|
||||
<Field
|
||||
type="email"
|
||||
id="outlined-basic"
|
||||
label="Email"
|
||||
placeholder="olivia@untitledui.com"
|
||||
error="This is an error message"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
{/* Now, illustration of the Website text fields */}
|
||||
|
||||
<WebsiteTextField hintText="This is a hint text to help user." />
|
||||
<WebsiteTextField
|
||||
hasCopyButton={true}
|
||||
hintText="This is a hint text to help user."
|
||||
/>
|
||||
{/* Now, illustration of the Website text fields */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "10px",
|
||||
maxWidth: "400px",
|
||||
padding: "10px",
|
||||
}}
|
||||
>
|
||||
<Field type="url" label="Website" />
|
||||
<Field type="url" label="Website" hasCopy={true} />
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
{/* Now, illustration of the Description text fields */}
|
||||
|
||||
<DescriptionTextField
|
||||
hasError={false}
|
||||
hintText="This is a hint text to help user."
|
||||
/>
|
||||
<DescriptionTextField
|
||||
hasError={true}
|
||||
hintText="This is a hint text to help user."
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "10px",
|
||||
maxWidth: "400px",
|
||||
padding: "10px",
|
||||
}}
|
||||
>
|
||||
<Field
|
||||
type="description"
|
||||
label="Description"
|
||||
placeholder="Enter a description... "
|
||||
/>
|
||||
<Field
|
||||
type="description"
|
||||
label="Description"
|
||||
placeholder="Enter a description... "
|
||||
error="This is an error message"
|
||||
/>
|
||||
</div>
|
||||
<hr />
|
||||
<PlayGroundCharts />
|
||||
<hr />
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
.register-page {
|
||||
width: var(--env-var-width-1);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-height: var(--env-var-height-1);
|
||||
@@ -40,16 +39,6 @@
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#register-firstname-input,
|
||||
#register-lastname-input,
|
||||
#register-email-input,
|
||||
#register-password-input {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
width: 294px;
|
||||
height: 11px;
|
||||
padding: 12px 14px;
|
||||
}
|
||||
|
||||
.register-bottom-spacing {
|
||||
height: 50px;
|
||||
}
|
||||
@@ -4,9 +4,6 @@ import { useNavigate } from "react-router-dom";
|
||||
import "./index.css";
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import Logomark from "../../assets/Images/Logomark.png";
|
||||
import EmailTextField from "../../Components/TextFields/Email/EmailTextField";
|
||||
import PasswordTextField from "../../Components/TextFields/Password/PasswordTextField";
|
||||
import StringTextField from "../../Components/TextFields/Text/TextField";
|
||||
import Check from "../../Components/Check/Check";
|
||||
import Button from "../../Components/Button";
|
||||
import Google from "../../assets/Images/Google.png";
|
||||
@@ -15,6 +12,7 @@ import axiosInstance from "../../Utils/axiosConfig";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { register } from "../../Features/Auth/authSlice";
|
||||
import { createToast } from "../../Utils/toastUtils";
|
||||
import Field from "../../Components/Inputs/Field";
|
||||
|
||||
const Register = () => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -119,6 +117,7 @@ const Register = () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div className="register-page">
|
||||
<BackgroundPattern></BackgroundPattern>
|
||||
@@ -137,42 +136,58 @@ const Register = () => {
|
||||
</div>
|
||||
<div className="register-form-v-spacing-40px" />
|
||||
<div className="register-form-inputs">
|
||||
<StringTextField
|
||||
onChange={handleInput}
|
||||
error={errors.firstname ? true : false}
|
||||
helperText={errors.firstname ? errors.firstname : ""}
|
||||
label="First name*"
|
||||
placeholder="Enter your first name"
|
||||
<Field
|
||||
id="register-firstname-input"
|
||||
label="Name"
|
||||
isRequired={true}
|
||||
placeholder="Talha"
|
||||
autoComplete="given-name"
|
||||
onChange={handleInput}
|
||||
error={errors.firstname}
|
||||
/>
|
||||
<div className="login-form-v2-spacing" />
|
||||
<StringTextField
|
||||
onChange={handleInput}
|
||||
error={errors.lastname ? true : false}
|
||||
helperText={errors.lastname ? errors.lastname : ""}
|
||||
label="Last name*"
|
||||
placeholder="Enter your last name"
|
||||
<Field
|
||||
id="register-lastname-input"
|
||||
label="Surname"
|
||||
isRequired={true}
|
||||
placeholder="Bolat"
|
||||
autoComplete="family-name"
|
||||
onChange={handleInput}
|
||||
error={errors.lastname}
|
||||
/>
|
||||
<div className="login-form-v2-spacing" />
|
||||
<EmailTextField
|
||||
onChange={handleInput}
|
||||
label="Email*"
|
||||
error={errors.email ? true : false}
|
||||
helperText={errors.email ? errors.email : ""}
|
||||
placeholder="Enter your email"
|
||||
autoComplete="email"
|
||||
<Field
|
||||
type="email"
|
||||
id="register-email-input"
|
||||
label="Email"
|
||||
isRequired={true}
|
||||
placeholder="name.surname@companyname.com"
|
||||
autoComplete="email"
|
||||
onChange={handleInput}
|
||||
error={errors.email}
|
||||
/>
|
||||
<div className="login-form-v2-spacing" />
|
||||
<PasswordTextField
|
||||
onChange={handleInput}
|
||||
label="Password*"
|
||||
error={errors.password ? true : false}
|
||||
helperText={errors.password ? errors.password : ""}
|
||||
<Field
|
||||
type="password"
|
||||
id="register-password-input"
|
||||
label="Password"
|
||||
isRequired={true}
|
||||
placeholder="Create a password"
|
||||
autoComplete="current-password"
|
||||
id="register-password-input"
|
||||
error={errors.password}
|
||||
onChange={handleInput}
|
||||
/>
|
||||
<div className="login-form-v2-spacing" />
|
||||
{/* TODO - hook up to form state and run checks */}
|
||||
<Field
|
||||
type="password"
|
||||
id="register-confirm-input"
|
||||
label="Confirm password"
|
||||
isRequired={true}
|
||||
placeholder="Confirm your password"
|
||||
autoComplete="current-password"
|
||||
error={errors.confirm}
|
||||
onChange={handleInput}
|
||||
/>
|
||||
</div>
|
||||
<div className="login-form-v2-spacing" />
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import "./index.css";
|
||||
import LockIcon from "../../assets/Images/lock-icon.png";
|
||||
import PasswordTextField from "../../Components/TextFields/Password/PasswordTextField";
|
||||
import Check from "../../Components/Check/Check";
|
||||
import Button from "../../Components/Button";
|
||||
import LeftArrow from "../../assets/Images/arrow-left.png";
|
||||
@@ -10,6 +9,7 @@ import { useState, useEffect } from "react";
|
||||
import { newPasswordValidation } from "../../Validation/validation";
|
||||
import axiosInstance from "../../Utils/axiosConfig";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Field from "../../Components/Inputs/Field";
|
||||
|
||||
const SetNewPassword = () => {
|
||||
const navigate = useNavigate();
|
||||
@@ -83,22 +83,24 @@ const SetNewPassword = () => {
|
||||
</div>
|
||||
<div className="set-new-password-form-gap-large"></div>
|
||||
<div className="set-new-password-form-content">
|
||||
<PasswordTextField
|
||||
label="Password"
|
||||
onChange={handleInput}
|
||||
error={errors.password !== undefined ? true : false}
|
||||
helperText={errors.password !== undefined ? errors.password : ""}
|
||||
placeholder="••••••••"
|
||||
<Field
|
||||
type="password"
|
||||
id="register-password-input"
|
||||
label="Password"
|
||||
isRequired={true}
|
||||
placeholder="••••••••"
|
||||
onChange={handleInput}
|
||||
error={errors.password}
|
||||
/>
|
||||
<div className="set-new-password-form-gap-medium"></div>
|
||||
<PasswordTextField
|
||||
label="Confirm password"
|
||||
onChange={handleInput}
|
||||
error={errors.confirm !== undefined ? true : false}
|
||||
helperText={errors.confirm !== undefined ? errors.confirm : ""}
|
||||
placeholder="••••••••"
|
||||
<Field
|
||||
type="password"
|
||||
id="confirm-password-input"
|
||||
label="Confirm password"
|
||||
isRequired={true}
|
||||
placeholder="••••••••"
|
||||
onChange={handleInput}
|
||||
error={errors.confirm}
|
||||
/>
|
||||
<div className="set-new-password-form-gap-medium"></div>
|
||||
<div className="set-new-password-form-checks">
|
||||
|
||||
@@ -91,6 +91,7 @@ const theme = createTheme({
|
||||
pY: "40px",
|
||||
},
|
||||
gap: {
|
||||
xs: "4px",
|
||||
small: "8px",
|
||||
medium: "12px",
|
||||
ml: "16px",
|
||||
@@ -101,7 +102,7 @@ const theme = createTheme({
|
||||
info: {
|
||||
color: secondaryMain,
|
||||
bg: otherColorsWhite,
|
||||
border: "#d0d5dd",
|
||||
border: sectionBorder,
|
||||
},
|
||||
error: {
|
||||
color: "#d92d20",
|
||||
@@ -111,7 +112,7 @@ const theme = createTheme({
|
||||
warning: {
|
||||
color: "#DC6803",
|
||||
bg: "#fffcf5",
|
||||
border: "#fec84b"
|
||||
border: "#fec84b",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-1-plus: 16px;
|
||||
--env-var-spacing-1-minus: 10px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
Reference in new issue
Block a user