Initial commit

This commit is contained in:
2026-02-27 15:01:06 +03:00
commit fc06bb6fcd
52 changed files with 1355 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
import { useEffect, useState } from "react";
import { apiGet } from "./api/client";
export default function App() {
const [salons, setSalons] = useState([]);
const [query, setQuery] = useState("");
const [status, setStatus] = useState("idle");
useEffect(() => {
let ignore = false;
async function load() {
setStatus("loading");
try {
const data = await apiGet(`/salons/?q=${encodeURIComponent(query)}`);
if (!ignore) {
setSalons(data);
setStatus("ready");
}
} catch (error) {
if (!ignore) {
setStatus("error");
}
}
}
load();
return () => {
ignore = true;
};
}, [query]);
return (
<div className="page">
<header className="hero">
<p className="eyebrow">Salon Booking Platform</p>
<h1>Find, compare, and book top salons near you.</h1>
<p className="subtitle">
Search by city or service, compare pricing, and lock in your slot in seconds.
</p>
<div className="search">
<input
type="text"
placeholder="Search by salon or service"
value={query}
onChange={(event) => setQuery(event.target.value)}
/>
</div>
</header>
<section className="results">
<h2>Salons</h2>
{status === "loading" && <p>Loading salons...</p>}
{status === "error" && (
<p className="error">Unable to load salons. Start the backend API to see results.</p>
)}
{status === "ready" && salons.length === 0 && <p>No salons found.</p>}
<div className="grid">
{salons.map((salon) => (
<article className="card" key={salon.id}>
<div className="card-header">
<h3>{salon.name}</h3>
<span className="rating">{salon.rating_avg} / 5</span>
</div>
<p>{salon.description || "No description yet."}</p>
<div className="meta">
<span>{salon.city}</span>
<span>{salon.phone_number || "Phone unavailable"}</span>
</div>
</article>
))}
</div>
</section>
</div>
);
}