151 lines
5.0 KiB
JavaScript
151 lines
5.0 KiB
JavaScript
import React from "react";
|
||
import CloseIcon from "../icons/CloseIcon";
|
||
|
||
// ─── Input field component ───────────────────────────────────────────────────
|
||
function InputField({ label, error, ...props }) {
|
||
return (
|
||
<div className="f-m-group">
|
||
<label className="f-m-label">{label}</label>
|
||
<input
|
||
className={`f-m-field${error ? " err" : ""}`}
|
||
{...props}
|
||
/>
|
||
{error && <p className="f-err-msg">{error}</p>}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── Image upload component ──────────────────────────────────────────────────
|
||
function ImageUpload({
|
||
displayImage,
|
||
imgError,
|
||
compressing,
|
||
fileInputRef,
|
||
onFileChange,
|
||
onRemove,
|
||
}) {
|
||
const MAX_SIZE_MB = 5;
|
||
|
||
return (
|
||
<div className="f-m-group">
|
||
<label className="f-m-label">Фото профиля</label>
|
||
{displayImage ? (
|
||
<div className="f-img-preview-wrap">
|
||
<img src={displayImage} alt="profile" className="f-img-preview" />
|
||
<button
|
||
className="f-img-remove"
|
||
onClick={onRemove}
|
||
type="button"
|
||
aria-label="Удалить фото"
|
||
>
|
||
<CloseIcon />
|
||
</button>
|
||
</div>
|
||
) : (
|
||
<label className="f-img-upload-label" aria-disabled={compressing}>
|
||
<input
|
||
ref={fileInputRef}
|
||
type="file"
|
||
accept="image/jpeg,image/png,image/webp"
|
||
onChange={onFileChange}
|
||
className="f-img-input"
|
||
disabled={compressing}
|
||
/>
|
||
{compressing ? <span>Обработка...</span> : <span>📷 Добавить фото</span>}
|
||
</label>
|
||
)}
|
||
{imgError && <p className="f-err-msg">{imgError}</p>}
|
||
<p className="f-hint">JPEG / PNG / WebP · до {MAX_SIZE_MB} МБ</p>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── Login field ─────────────────────────────────────────────────────────────
|
||
function LoginField({ form, errors, onChange }) {
|
||
return (
|
||
<InputField
|
||
label="Логин"
|
||
placeholder="username"
|
||
value={form.login}
|
||
error={errors.login}
|
||
onChange={(e) => onChange("login", e.target.value)}
|
||
/>
|
||
);
|
||
}
|
||
|
||
// ─── Name fields row ─────────────────────────────────────────────────────────
|
||
function NameFieldsRow({ form, errors, onChange }) {
|
||
return (
|
||
<div className="f-m-row">
|
||
<InputField
|
||
label="Имя"
|
||
placeholder="Иван"
|
||
value={form.firstName}
|
||
error={errors.firstName}
|
||
onChange={(e) => onChange("firstName", e.target.value)}
|
||
/>
|
||
<InputField
|
||
label="Фамилия"
|
||
placeholder="Иванов"
|
||
value={form.lastName}
|
||
error={errors.lastName}
|
||
onChange={(e) => onChange("lastName", e.target.value)}
|
||
/>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── Contact fields ─────────────────────────────────────────────────────────
|
||
function ContactFields({ form, errors, onChange, onPhoneChange }) {
|
||
return (
|
||
<>
|
||
<InputField
|
||
label="Номер телефона"
|
||
type="tel"
|
||
placeholder="+7 (___) ___-__-__"
|
||
value={form.phone}
|
||
error={errors.phone}
|
||
onChange={(e) => onPhoneChange(e.target.value)}
|
||
/>
|
||
<InputField
|
||
label="Электронная почта"
|
||
type="email"
|
||
placeholder="example@email.com"
|
||
value={form.email}
|
||
error={errors.email}
|
||
onChange={(e) => onChange("email", e.target.value)}
|
||
/>
|
||
</>
|
||
);
|
||
}
|
||
|
||
// ─── Submit button ──────────────────────────────────────────────────────────
|
||
function SubmitButton({ loading, onSubmit }) {
|
||
return (
|
||
<button
|
||
className="f-m-submit"
|
||
onClick={onSubmit}
|
||
disabled={loading}
|
||
>
|
||
<div className="f-m-submit-row">
|
||
{loading && <div className="f-m-spinner" />}
|
||
Сохранить профиль
|
||
</div>
|
||
</button>
|
||
);
|
||
}
|
||
|
||
// ─── Modal header ──────────────────────────────────────────────────────────
|
||
function ModalHeader({ onClose }) {
|
||
return (
|
||
<div className="f-modal-head">
|
||
<span className="f-modal-title">Редактирование профиля</span>
|
||
<button className="f-close-btn" onClick={onClose}>
|
||
<CloseIcon />
|
||
</button>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export { InputField, ImageUpload, LoginField, NameFieldsRow, ContactFields, SubmitButton, ModalHeader };
|