feat(settings): use-my-current-location button; surface ticket-load error
CI/CD / CI · Admin API (dotnet build) (push) Successful in 52s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 36s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / CI · API (dotnet build + test) (push) Successful in 41s
CI/CD / Deploy · all services (push) Failing after 2m34s

Location card gets a 'موقعیت فعلی من' button that fills lat/lng from the browser's geolocation. Support ticket list now shows the resolved (localized) error instead of a generic message, so a failure is diagnosable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-02 01:52:29 +03:30
parent e839db7331
commit 087563bce7
2 changed files with 24 additions and 1 deletions
@@ -366,6 +366,26 @@ export function SettingsShopPanel({ cafeId }: SettingsShopPanelProps) {
> >
ذخیره موقعیت ذخیره موقعیت
</Button> </Button>
<Button
variant="outline"
onClick={() => {
if (typeof navigator === "undefined" || !navigator.geolocation) {
notify.error("مرورگر شما موقعیت‌یابی را پشتیبانی نمی‌کند");
return;
}
navigator.geolocation.getCurrentPosition(
(pos) => {
setLatInput(pos.coords.latitude.toFixed(5));
setLngInput(pos.coords.longitude.toFixed(5));
setLocationError(null);
},
() => notify.error("دسترسی به موقعیت امکان‌پذیر نبود. لطفاً اجازه دسترسی بدهید."),
{ enableHighAccuracy: true, timeout: 10000 }
);
}}
>
موقعیت فعلی من
</Button>
{(latInput || lngInput) && ( {(latInput || lngInput) && (
<Button <Button
variant="ghost" variant="ghost"
@@ -6,6 +6,7 @@ import { useState } from "react";
import { useParams } from "next/navigation"; import { useParams } from "next/navigation";
import { Link } from "@/i18n/routing"; import { Link } from "@/i18n/routing";
import { apiGet, apiPost } from "@/lib/api/client"; import { apiGet, apiPost } from "@/lib/api/client";
import { useApiError } from "@/lib/use-api-error";
import { useAuthStore } from "@/lib/stores/auth.store"; import { useAuthStore } from "@/lib/stores/auth.store";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
@@ -52,6 +53,7 @@ function formatDate(iso: string) {
export function SupportScreen() { export function SupportScreen() {
const t = useTranslations("support"); const t = useTranslations("support");
const apiError = useApiError();
const cafeId = useAuthStore((s) => s.user?.cafeId); const cafeId = useAuthStore((s) => s.user?.cafeId);
const [subject, setSubject] = useState(""); const [subject, setSubject] = useState("");
const [body, setBody] = useState(""); const [body, setBody] = useState("");
@@ -61,6 +63,7 @@ export function SupportScreen() {
data: tickets = [], data: tickets = [],
isLoading, isLoading,
isError, isError,
error,
refetch, refetch,
} = useQuery({ } = useQuery({
queryKey: ["support", cafeId], queryKey: ["support", cafeId],
@@ -135,7 +138,7 @@ export function SupportScreen() {
</p> </p>
{isError ? ( {isError ? (
<Card className="rounded-xl border border-destructive/30 p-4 text-sm text-destructive"> <Card className="rounded-xl border border-destructive/30 p-4 text-sm text-destructive">
<p>{t("loadFailed")}</p> <p>{apiError(error, t("loadFailed"))}</p>
<Button variant="outline" size="sm" className="mt-2" onClick={() => void refetch()}> <Button variant="outline" size="sm" className="mt-2" onClick={() => void refetch()}>
{t("retry")} {t("retry")}
</Button> </Button>