Merge pull request #34 from SlimusMinus/add-rules_accepted
added checkbox rules_accepted in post
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import {useCallback, useEffect, useState} from "react";
|
import {useCallback, useEffect, useState} from "react";
|
||||||
import CloseIcon from "./icons/CloseIcon";
|
import CloseIcon from "./icons/CloseIcon";
|
||||||
|
import RulesModal from "./RulesModal";
|
||||||
import { EMPTY_FORM, CATEGORY_KEYS } from "../config/feedConstants";
|
import { EMPTY_FORM, CATEGORY_KEYS } from "../config/feedConstants";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { usePostMutation } from "../hooks/usePostMutation";
|
import { usePostMutation } from "../hooks/usePostMutation";
|
||||||
@@ -32,12 +33,13 @@ export default function CreateUpdatePost({ onClose, onSuccess, initialData }) {
|
|||||||
category: initialData.category || "",
|
category: initialData.category || "",
|
||||||
date: initialData.date || "",
|
date: initialData.date || "",
|
||||||
phone: initialData.phone || "",
|
phone: initialData.phone || "",
|
||||||
address: initialData.city || ""
|
address: initialData.city || "",
|
||||||
|
rulesAccepted: true
|
||||||
}
|
}
|
||||||
: EMPTY_FORM
|
: EMPTY_FORM
|
||||||
);
|
);
|
||||||
|
|
||||||
// Ошибки валидации — ключ совпадает с именем поля
|
const [rulesModalOpen, setRulesModalOpen] = useState(false);
|
||||||
const [errors, setErrors] = useState({});
|
const [errors, setErrors] = useState({});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -125,6 +127,8 @@ export default function CreateUpdatePost({ onClose, onSuccess, initialData }) {
|
|||||||
data.append("address", form.address.trim());
|
data.append("address", form.address.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.append("rulesAccepted", form.rulesAccepted ? "true" : "false");
|
||||||
|
|
||||||
// save(id, data): id = null → POST (создание), id = string → PUT (обновление)
|
// save(id, data): id = null → POST (создание), id = string → PUT (обновление)
|
||||||
const result = await save(isEdit ? initialData.id : null, data);
|
const result = await save(isEdit ? initialData.id : null, data);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@@ -307,6 +311,32 @@ export default function CreateUpdatePost({ onClose, onSuccess, initialData }) {
|
|||||||
{errors.phone && <p className="f-err-msg">{errors.phone}</p>}
|
{errors.phone && <p className="f-err-msg">{errors.phone}</p>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Чекбокс согласия с правилами */}
|
||||||
|
<div className="f-m-group">
|
||||||
|
<label className="f-rules-checkbox">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="f-rules-input"
|
||||||
|
checked={form.rulesAccepted}
|
||||||
|
onChange={e => set("rulesAccepted", e.target.checked)}
|
||||||
|
/>
|
||||||
|
<span className="f-rules-checkmark" />
|
||||||
|
<span className="f-rules-text">
|
||||||
|
{t('post.rulesCheckboxPrefix')}{' '}
|
||||||
|
<span
|
||||||
|
className="f-rules-link"
|
||||||
|
onClick={e => {
|
||||||
|
e.preventDefault();
|
||||||
|
setRulesModalOpen(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('post.rulesLinkText')}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
{errors.rulesAccepted && <p className="f-err-msg">{errors.rulesAccepted}</p>}
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Глобальная ошибка API (не связана с конкретным полем) */}
|
{/* Глобальная ошибка API (не связана с конкретным полем) */}
|
||||||
{apiError && <p className="f-err-msg">{apiError}</p>}
|
{apiError && <p className="f-err-msg">{apiError}</p>}
|
||||||
|
|
||||||
@@ -321,6 +351,11 @@ export default function CreateUpdatePost({ onClose, onSuccess, initialData }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* ── Модалка с правилами площадки ── */}
|
||||||
|
{rulesModalOpen && (
|
||||||
|
<RulesModal onClose={() => setRulesModalOpen(false)} />
|
||||||
|
)}
|
||||||
|
|
||||||
{/* ── Модалка-результат после отправки ── */}
|
{/* ── Модалка-результат после отправки ── */}
|
||||||
{resultModal && (
|
{resultModal && (
|
||||||
<div className="f-modal-bg" onClick={e => {
|
<div className="f-modal-bg" onClick={e => {
|
||||||
|
|||||||
@@ -23,5 +23,6 @@ export const EMPTY_FORM = {
|
|||||||
location: "",
|
location: "",
|
||||||
phone: "",
|
phone: "",
|
||||||
date: "",
|
date: "",
|
||||||
address: ""
|
address: "",
|
||||||
|
rulesAccepted: false
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -253,6 +253,41 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Rules Checkbox ── */
|
||||||
|
.f-rules-checkbox {
|
||||||
|
display: flex; align-items: center; gap: 10px; cursor: pointer;
|
||||||
|
user-select: none; padding: 6px 0;
|
||||||
|
}
|
||||||
|
.f-rules-input {
|
||||||
|
position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
|
||||||
|
}
|
||||||
|
.f-rules-checkmark {
|
||||||
|
flex-shrink: 0; width: 20px; height: 20px;
|
||||||
|
border: 2px solid var(--border); border-radius: 5px;
|
||||||
|
background: var(--bg-input); transition: all .2s;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.f-rules-input:checked + .f-rules-checkmark {
|
||||||
|
background: var(--teal); border-color: var(--teal);
|
||||||
|
}
|
||||||
|
.f-rules-input:checked + .f-rules-checkmark::after {
|
||||||
|
content: ""; position: absolute; left: 5px; top: 1px;
|
||||||
|
width: 6px; height: 10px;
|
||||||
|
border: solid #082320; border-width: 0 2.5px 2.5px 0;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
.f-rules-input:focus + .f-rules-checkmark {
|
||||||
|
box-shadow: 0 0 0 3px rgba(var(--teal-rgb), .25);
|
||||||
|
}
|
||||||
|
.f-rules-text {
|
||||||
|
font-size: .82rem; color: var(--muted); line-height: 1.4;
|
||||||
|
}
|
||||||
|
.f-rules-link {
|
||||||
|
color: var(--teal); cursor: pointer; text-decoration: underline;
|
||||||
|
text-underline-offset: 2px; transition: opacity .15s;
|
||||||
|
}
|
||||||
|
.f-rules-link:hover { opacity: .75; }
|
||||||
|
|
||||||
/* ── Result Modal (success / blocked) ── */
|
/* ── Result Modal (success / blocked) ── */
|
||||||
.f-modal-result {
|
.f-modal-result {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@@ -6,5 +6,6 @@ export function validatePostForm(form) {
|
|||||||
if (!form.description.trim()) errors.description = i18n.t('validation.descriptionRequired');
|
if (!form.description.trim()) errors.description = i18n.t('validation.descriptionRequired');
|
||||||
if (!form.category) errors.category = i18n.t('validation.categoryRequired');
|
if (!form.category) errors.category = i18n.t('validation.categoryRequired');
|
||||||
if (!form.phone.trim()) errors.phone = i18n.t('validation.phoneRequired');
|
if (!form.phone.trim()) errors.phone = i18n.t('validation.phoneRequired');
|
||||||
|
if (!form.rulesAccepted) errors.rulesAccepted = i18n.t('validation.rulesRequired');
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user