Merge pull request #7 from SlimusMinus/connect_post_back
added get and create posts with back
This commit is contained in:
@@ -1,19 +1,17 @@
|
|||||||
import {useCallback, useState} from "react";
|
import {useCallback, useState} from "react";
|
||||||
import {API_URL} from "../config/constants";
|
|
||||||
import PinIcon from "./icons/PinIcon";
|
import PinIcon from "./icons/PinIcon";
|
||||||
import CloseIcon from "./icons/CloseIcon";
|
import CloseIcon from "./icons/CloseIcon";
|
||||||
import { EMPTY_FORM, CATEGORIES } from "../config/feedConstants";
|
import { EMPTY_FORM, CATEGORIES } from "../config/feedConstants";
|
||||||
|
import { useCreatePost } from "../hooks/useCreatePost";
|
||||||
|
|
||||||
export default function PostModal({ onClose, onSuccess }) {
|
export default function PostModal({ onClose, onSuccess }) {
|
||||||
const [form, setForm] = useState(EMPTY_FORM);
|
const [form, setForm] = useState(EMPTY_FORM);
|
||||||
const [errors, setErrors] = useState({});
|
const [errors, setErrors] = useState({});
|
||||||
const [loading, setLoading] = useState(false);
|
const { createAd, loading, error: apiError } = useCreatePost();
|
||||||
const [apiError, setApiError] = useState("");
|
|
||||||
|
|
||||||
const set = useCallback((k, v) => {
|
const set = useCallback((k, v) => {
|
||||||
setForm(p => ({ ...p, [k]: v }));
|
setForm(p => ({ ...p, [k]: v }));
|
||||||
setErrors(p => ({ ...p, [k]: "" }));
|
setErrors(p => ({ ...p, [k]: "" }));
|
||||||
setApiError("");
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const validate = () => {
|
const validate = () => {
|
||||||
@@ -28,25 +26,20 @@ export default function PostModal({ onClose, onSuccess }) {
|
|||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!validate()) return;
|
if (!validate()) return;
|
||||||
setLoading(true);
|
|
||||||
setApiError("");
|
const payload = {
|
||||||
try {
|
type: form.type, // "loss" | "found"
|
||||||
const res = await fetch(`${API_URL}/api/ads`, {
|
title: form.title.trim(),
|
||||||
method: "POST",
|
description: form.description.trim(),
|
||||||
headers: { "Content-Type": "application/json" },
|
category: form.category,
|
||||||
body: JSON.stringify(form),
|
date: form.date || null,
|
||||||
});
|
phone: form.phone.trim(),
|
||||||
if (!res.ok) {
|
};
|
||||||
const data = await res.json().catch(() => ({}));
|
|
||||||
throw new Error(data.message || `Ошибка ${res.status}`);
|
const newAd = await createAd(payload);
|
||||||
}
|
if (newAd) {
|
||||||
const newAd = await res.json();
|
|
||||||
onSuccess(newAd);
|
onSuccess(newAd);
|
||||||
onClose();
|
onClose();
|
||||||
} catch (err) {
|
|
||||||
setApiError(err.message || "Не удалось разместить объявление");
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -107,15 +100,7 @@ export default function PostModal({ onClose, onSuccess }) {
|
|||||||
</select>
|
</select>
|
||||||
{errors.category && <p className="f-err-msg">{errors.category}</p>}
|
{errors.category && <p className="f-err-msg">{errors.category}</p>}
|
||||||
</div>
|
</div>
|
||||||
<div className="f-m-group">
|
|
||||||
<label className="f-m-label">Дата события</label>
|
|
||||||
<input
|
|
||||||
className="f-m-field"
|
|
||||||
type="date"
|
|
||||||
value={form.date}
|
|
||||||
onChange={e => set("date", e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="f-m-group">
|
<div className="f-m-group">
|
||||||
|
|||||||
42
src/hooks/useCreatePost.js
Normal file
42
src/hooks/useCreatePost.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { API_URL } from "../config/constants";
|
||||||
|
|
||||||
|
export function useCreatePost() {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [error, setError] = useState(null);
|
||||||
|
const [success, setSuccess] = useState(false);
|
||||||
|
|
||||||
|
const createAd = async (adData) => {
|
||||||
|
setLoading(true);
|
||||||
|
setError(null);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const token = localStorage.getItem("token");
|
||||||
|
|
||||||
|
const res = await fetch(`${API_URL}/api/v1/posts`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify(adData),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error(data.message || "Ошибка при создании объявления");
|
||||||
|
}
|
||||||
|
|
||||||
|
setSuccess(true);
|
||||||
|
return data; // возвращает созданное объявление
|
||||||
|
} catch (e) {
|
||||||
|
setError(e.message);
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return { createAd, loading, error, success };
|
||||||
|
}
|
||||||
@@ -7,7 +7,6 @@ import AdCard from "../components/AdCard";
|
|||||||
import PostModal from "../components/PostModal";
|
import PostModal from "../components/PostModal";
|
||||||
import MenuIcon from "../components/icons/MenuIcon"
|
import MenuIcon from "../components/icons/MenuIcon"
|
||||||
|
|
||||||
// ─── FEED PAGE ────────────────────────────────────────────────────────────────
|
|
||||||
export default function FeedPage() {
|
export default function FeedPage() {
|
||||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||||
const [activeNav, setActiveNav] = useState("Главная");
|
const [activeNav, setActiveNav] = useState("Главная");
|
||||||
@@ -17,13 +16,12 @@ export default function FeedPage() {
|
|||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
|
|
||||||
// Загрузка объявлений с бэка
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const load = async () => {
|
const load = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError("");
|
setError("");
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${API_URL}/api/ads`);
|
const res = await fetch(`${API_URL}/api/v1/posts`);
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
throw new Error(`Ошибка ${res.status}`);
|
throw new Error(`Ошибка ${res.status}`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user