diff --git a/app/(dashboard)/dashboard/shop/page.tsx b/app/(dashboard)/dashboard/shop/page.tsx
index 8df8019..87d22aa 100644
--- a/app/(dashboard)/dashboard/shop/page.tsx
+++ b/app/(dashboard)/dashboard/shop/page.tsx
@@ -7,50 +7,99 @@ import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Separator } from "@/components/ui/separator"
import { Textarea } from "@/components/ui/textarea"
-import { resolveOwnerShop } from "@/lib/domain/resolve-current-shop"
+import { addShopAnnouncement, deleteShopAnnouncement, updateShop } from "@/lib/api"
+import { toApiError } from "@/lib/errors"
+import { useMyShop } from "@/lib/hooks/use-my-shop"
+import { notifyInfo, notifySuccess } from "@/lib/toast"
import type { Shop } from "@/lib/types"
-import { useAuthStore } from "@/store/auth"
-import { useShopStore } from "@/store/shops"
import { DollarSign, Edit, ExternalLink, ListOrdered, Star, Users } from "lucide-react"
import Link from "next/link"
import { useState } from "react"
export default function ShopManagementPage() {
- const userId = useAuthStore((state) => state.user?.id)
- const shops = useShopStore((state) => state.shops)
- const shop = resolveOwnerShop(userId, shops)
- const updateShop = useShopStore((state) => state.updateShop)
- const updateAnnouncement = useShopStore((state) => state.updateAnnouncement)
- const addAnnouncement = useShopStore((state) => state.addAnnouncement)
+ const { shop, setShop, loading, error, refreshShop } = useMyShop()
+
+ if (loading) {
+ return
加载中...
+ }
+
+ if (error) {
+ return {error}
+ }
if (!shop) {
return 当前账号没有可管理的店铺
}
return (
-
+
)
}
function ShopManagementContent({
shop,
- updateShop,
- updateAnnouncement,
- addAnnouncement,
+ setShop,
+ refreshShop,
}: {
shop: Shop
- updateShop: (shopId: string, patch: Partial>) => void
- updateAnnouncement: (shopId: string, index: number, announcement: string) => void
- addAnnouncement: (shopId: string, announcement: string) => void
+ setShop: (shop: Shop | null) => void
+ refreshShop: () => Promise
}) {
const [name, setName] = useState(shop.name)
const [description, setDescription] = useState(shop.description)
+ const [saving, setSaving] = useState(false)
+
+ const handleSave = async () => {
+ setSaving(true)
+ try {
+ const nextShop = await updateShop(shop.id, {
+ name,
+ description,
+ commissionType: shop.commissionType,
+ commissionValue: shop.commissionValue,
+ allowMultiShop: shop.allowMultiShop,
+ allowIndependentOrders: shop.allowIndependentOrders,
+ dispatchMode: shop.dispatchMode,
+ })
+ setShop(nextShop)
+ notifySuccess("店铺信息已保存")
+ } catch (error) {
+ notifyInfo(toApiError(error).msg)
+ } finally {
+ setSaving(false)
+ }
+ }
+
+ const handleAddAnnouncement = async () => {
+ const next = window.prompt("", "")
+ if (next === null) return
+ const value = next.trim()
+ if (!value) return
+
+ setSaving(true)
+ try {
+ await addShopAnnouncement(shop.id, value)
+ await refreshShop()
+ notifySuccess("公告已添加")
+ } catch (error) {
+ notifyInfo(toApiError(error).msg)
+ } finally {
+ setSaving(false)
+ }
+ }
+
+ const handleDeleteAnnouncement = async (index: number) => {
+ setSaving(true)
+ try {
+ await deleteShopAnnouncement(shop.id, index)
+ await refreshShop()
+ notifySuccess("公告已删除")
+ } catch (error) {
+ notifyInfo(toApiError(error).msg)
+ } finally {
+ setSaving(false)
+ }
+ }
return (
@@ -126,12 +175,10 @@ function ShopManagementContent({
/>
diff --git a/app/(dashboard)/dashboard/shop/rules/page.tsx b/app/(dashboard)/dashboard/shop/rules/page.tsx
index f524792..d5c7c37 100644
--- a/app/(dashboard)/dashboard/shop/rules/page.tsx
+++ b/app/(dashboard)/dashboard/shop/rules/page.tsx
@@ -12,54 +12,71 @@ import {
SelectValue,
} from "@/components/ui/select"
import { Switch } from "@/components/ui/switch"
-import { resolveOwnerShop } from "@/lib/domain/resolve-current-shop"
+import { updateShop } from "@/lib/api"
+import { toApiError } from "@/lib/errors"
+import { useMyShop } from "@/lib/hooks/use-my-shop"
+import { notifyInfo, notifySuccess } from "@/lib/toast"
import type { Shop } from "@/lib/types"
-import { useAuthStore } from "@/store/auth"
-import { useShopStore } from "@/store/shops"
import { Save } from "lucide-react"
import { useState } from "react"
export default function ShopRulesPage() {
- const userId = useAuthStore((state) => state.user?.id)
- const shops = useShopStore((state) => state.shops)
- const shop = resolveOwnerShop(userId, shops)
- const updateShop = useShopStore((state) => state.updateShop)
+ const { shop, setShop, loading, error } = useMyShop()
+
+ if (loading) {
+ return 加载中...
+ }
+
+ if (error) {
+ return {error}
+ }
if (!shop) {
return 当前账号没有可管理的店铺
}
- return
+ return
}
-function ShopRulesForm({
- shop,
- updateShop,
-}: {
- shop: Shop
- updateShop: (shopId: string, patch: Partial>) => void
-}) {
+function ShopRulesForm({ shop, setShop }: { shop: Shop; setShop: (shop: Shop | null) => void }) {
const [commissionType, setCommissionType] = useState(shop.commissionType)
const [commissionValue, setCommissionValue] = useState(shop.commissionValue)
const [allowMultiShop, setAllowMultiShop] = useState(shop.allowMultiShop)
const [allowIndependentOrders, setAllowIndependentOrders] = useState(shop.allowIndependentOrders)
const [dispatchMode, setDispatchMode] = useState(shop.dispatchMode)
+ const [saving, setSaving] = useState(false)
- const handleSave = () => {
- updateShop(shop.id, {
- commissionType,
- commissionValue,
- allowMultiShop,
- allowIndependentOrders,
- dispatchMode,
- })
+ const handleSave = async () => {
+ setSaving(true)
+ try {
+ const nextShop = await updateShop(shop.id, {
+ name: shop.name,
+ description: shop.description,
+ commissionType,
+ commissionValue,
+ allowMultiShop,
+ allowIndependentOrders,
+ dispatchMode,
+ })
+ setShop(nextShop)
+ notifySuccess("规则已保存")
+ } catch (error) {
+ notifyInfo(toApiError(error).msg)
+ } finally {
+ setSaving(false)
+ }
}
return (
规则设置
-
diff --git a/lib/hooks/use-my-shop.ts b/lib/hooks/use-my-shop.ts
new file mode 100644
index 0000000..1604fc3
--- /dev/null
+++ b/lib/hooks/use-my-shop.ts
@@ -0,0 +1,62 @@
+"use client"
+
+import { getMyShop } from "@/lib/api/shops"
+import { toApiError } from "@/lib/errors"
+import type { Shop } from "@/lib/types"
+import { useCallback, useEffect, useState } from "react"
+
+export function useMyShop() {
+ const [shop, setShop] = useState(null)
+ const [loading, setLoading] = useState(true)
+ const [error, setError] = useState(null)
+
+ const refreshShop = useCallback(async () => {
+ setLoading(true)
+ setError(null)
+
+ try {
+ const nextShop = (await getMyShop()) ?? null
+ setShop(nextShop)
+ return nextShop
+ } catch (error) {
+ setShop(null)
+ setError(
+ error instanceof Error && error.message === "UNAUTHORIZED"
+ ? "请先登录"
+ : toApiError(error).msg,
+ )
+ return null
+ } finally {
+ setLoading(false)
+ }
+ }, [])
+
+ useEffect(() => {
+ let cancelled = false
+
+ getMyShop()
+ .then((nextShop) => {
+ if (cancelled) return
+ setShop(nextShop ?? null)
+ })
+ .catch((error) => {
+ if (cancelled) return
+ setShop(null)
+ setError(
+ error instanceof Error && error.message === "UNAUTHORIZED"
+ ? "请先登录"
+ : toApiError(error).msg,
+ )
+ })
+ .finally(() => {
+ if (cancelled) return
+ setLoading(false)
+ })
+
+ return () => {
+ cancelled = true
+ }
+ }, [])
+
+ return { shop, setShop, loading, error, refreshShop }
+}