feat: OTP flow, first page

This commit is contained in:
Afra ‌ 2026-06-21 12:47:37 +03:30
parent d02a96cce0
commit 0cc04919be
3 changed files with 76 additions and 2 deletions

View file

@ -9,6 +9,7 @@ import CafeOwnerPanel from './pages/CafeOwnerPanel'
import AddEvent from './pages/AddEvent'
import AddEventSuccess from './pages/AddEventSuccess'
import EventReservations from './pages/EventReservations'
import Login from './pages/Login'
function ScrollToTop() {
const { pathname } = useLocation()
@ -34,6 +35,7 @@ export default function App() {
<Route path="/owner/events/new" element={<AddEvent />} />
<Route path="/owner/events/success" element={<AddEventSuccess />} />
<Route path="/owner/events/:id/reservations" element={<EventReservations />} />
<Route path="/login" element={<Login />} />
</Routes>
</BrowserRouter>
)

View file

@ -209,8 +209,10 @@ export default function CafeDetail() {
className="h-48 w-full overflow-hidden rounded-2xl"
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution="&copy; Addwin Maps"
url="https://maps.addwin.ir/styles/basic/{z}/{x}/{y}.png"
maxZoom={19}
minZoom={8}
/>
<Marker position={[cafe.location.lat, cafe.location.lng]} />
<ZoomControl position="topright" />

70
src/pages/Login.tsx Normal file
View file

@ -0,0 +1,70 @@
import { useState } from "react";
function CheckIcon() {
return (
<svg
className="h-3 w-3 text-white"
viewBox="0 0 12 12"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M2.5 6.5L4.5 8.5L9.5 3.5" />
</svg>
);
}
export default function Login() {
const [phone, setPhone] = useState("");
const [acceptedTerms, setAcceptedTerms] = useState(false);
const canContinue = phone.trim().length > 0 && acceptedTerms;
return (
<div className="flex min-h-screen flex-col justify-center px-6">
<h1 className="text-right text-2xl font-bold text-gray-900">
ورود به وینسو
</h1>
<p className="mt-2 text-right text-gray-500">
لطفا شماره تماس خود را وارد کنید.
</p>
<input
type="text"
inputMode="numeric"
value={phone}
onChange={(e) => setPhone(e.target.value)}
placeholder="مثال: ۰۹۱۲۳۴۵۶۷۸۹"
className="mt-6 h-14 w-full rounded-lg border border-gray-200 bg-[#F8F8F8] px-4 text-right placeholder:font-light placeholder:text-[#999999]"
/>
<button
type="button"
disabled={!canContinue}
className="mt-4 w-full flex justify-center items-center h-12 rounded-2xl bg-[#223D5D] py-4 text-lg font-semibold text-white disabled:opacity-50"
>
ادامه
</button>
<div className="mt-4 flex items-center justify-center gap-2">
<button
type="button"
onClick={() => setAcceptedTerms((v) => !v)}
className={`flex h-5 w-5 shrink-0 items-center justify-center rounded-md border-2 border-[#223D5D] ${
acceptedTerms ? "bg-[#223D5D]" : "bg-transparent"
}`}
>
{acceptedTerms && <CheckIcon />}
</button>
<p className="text-sm text-gray-600">
<a href="#" className="text-[#223D5D] underline">
قوانین و شرایط
</a>{" "}
را می‌پذیرم.
</p>
</div>
</div>
);
}