Files
nahodka-front/src/components/profile/ProfileFormFields.jsx
2026-06-18 00:25:13 +03:00

151 lines
5.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 };