feat(partner): let staff manage stores and fix env photo dupes
CI / verify (pull_request) Has been cancelled
CI / verify (pull_request) Has been cancelled
Allow store:create/manage sub-accounts to edit, open/close, and re-upload media; dedupe ENV photos on write/read and replace via media API. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import { isLoggedIn, request } from '../lib/api';
|
||||
import { usePartnerSession } from '../contexts/PartnerSessionContext';
|
||||
import { isSubAccount } from '../lib/partnerAccess';
|
||||
import { canCreatePartnerStore, canManagePartnerStore } from '../lib/partnerAccess';
|
||||
import {
|
||||
canPartnerOpenStore,
|
||||
storeAuditLabel,
|
||||
@@ -27,7 +27,8 @@ export default function StoreListPage() {
|
||||
const navigate = useNavigate();
|
||||
const [searchParams] = useSearchParams();
|
||||
const { account } = usePartnerSession();
|
||||
const readonly = isSubAccount(account);
|
||||
const canMutate = canManagePartnerStore(account);
|
||||
const canCreate = canCreatePartnerStore(account);
|
||||
const [stores, setStores] = useState<Array<Record<string, unknown>>>([]);
|
||||
const [q, setQ] = useState('');
|
||||
const initialFilter = (searchParams.get('audit') === 'pending' ? 'PENDING_AUDIT' : 'ALL') as StatusFilter;
|
||||
@@ -45,8 +46,8 @@ export default function StoreListPage() {
|
||||
}, [navigate, loadStores]);
|
||||
|
||||
useEffect(() => {
|
||||
document.title = readonly ? '我的门店' : '门店管理';
|
||||
}, [readonly]);
|
||||
document.title = canMutate ? '门店管理' : '我的门店';
|
||||
}, [canMutate]);
|
||||
|
||||
const filtered = useMemo(() => stores.filter((s) => {
|
||||
const matchQ = !q || String(s.name).includes(q) || String(s.address).includes(q);
|
||||
@@ -101,12 +102,14 @@ export default function StoreListPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{canCreate && (
|
||||
<Link to="/stores/new" className="partner-fab-link">
|
||||
<button type="button" className="partner-btn-primary">
|
||||
<span className="material-symbols-outlined">add_business</span>
|
||||
录入新门店
|
||||
</button>
|
||||
</Link>
|
||||
)}
|
||||
|
||||
{filtered.length === 0 && <div className="empty">暂无门店</div>}
|
||||
|
||||
@@ -146,7 +149,7 @@ export default function StoreListPage() {
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
{!readonly && (
|
||||
{canMutate && (
|
||||
<div className="partner-store-card-actions">
|
||||
<button
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user