@spree/seller-dashboard 6.0.2 → 6.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/package.json +23 -23
  2. package/src/api-client.ts +2 -0
  3. package/src/components/account-dialog.tsx +1 -1
  4. package/src/components/centered-message.tsx +1 -1
  5. package/src/components/finance/balance-summary.tsx +1 -1
  6. package/src/components/orders/fulfillment-deliveries.tsx +1 -1
  7. package/src/components/orders/fulfillments-card.tsx +30 -20
  8. package/src/components/orders/order-cards.tsx +115 -102
  9. package/src/components/orders/order-payment-card.tsx +2 -3
  10. package/src/components/orders/post-sale-cards.tsx +79 -47
  11. package/src/components/orders/post-sale-create-dialogs.tsx +15 -0
  12. package/src/components/orders/returns-card.tsx +44 -36
  13. package/src/components/orders/shipping-label-row.tsx +1 -1
  14. package/src/components/orders/use-product-link.tsx +10 -0
  15. package/src/components/product-status-card.tsx +2 -2
  16. package/src/components/seller-address-card.tsx +2 -2
  17. package/src/components/seller-returns-location-card.tsx +2 -7
  18. package/src/components/seller-switcher.tsx +1 -1
  19. package/src/hooks/use-fulfillments.ts +33 -22
  20. package/src/hooks/use-profile.ts +38 -0
  21. package/src/locales/ar.json +37 -32
  22. package/src/locales/de.json +37 -32
  23. package/src/locales/en.json +37 -32
  24. package/src/locales/fr.json +37 -32
  25. package/src/locales/ja.json +37 -32
  26. package/src/locales/pl.json +37 -32
  27. package/src/locales/vi.json +37 -32
  28. package/src/locales/zh-CN.json +37 -32
  29. package/src/nav/default.ts +0 -10
  30. package/src/nav/settings.ts +53 -0
  31. package/src/pages/delivery-methods.tsx +47 -49
  32. package/src/pages/forgot-password.tsx +5 -5
  33. package/src/pages/general-settings.tsx +233 -0
  34. package/src/pages/home.tsx +1 -1
  35. package/src/pages/login.tsx +3 -3
  36. package/src/pages/onboarding.tsx +26 -23
  37. package/src/pages/order.tsx +2 -1
  38. package/src/pages/orders.tsx +8 -15
  39. package/src/pages/payout.tsx +7 -4
  40. package/src/pages/payouts.tsx +23 -2
  41. package/src/pages/policies.tsx +12 -8
  42. package/src/pages/product.tsx +18 -4
  43. package/src/pages/products.tsx +0 -4
  44. package/src/pages/profile-settings.tsx +221 -0
  45. package/src/pages/reset-password.tsx +3 -3
  46. package/src/pages/seller-picker.tsx +1 -1
  47. package/src/pages/taxes.tsx +40 -0
  48. package/src/pages/team.tsx +1 -1
  49. package/src/routeTree.gen.ts +63 -0
  50. package/src/routes/_authenticated/$sellerId/profile.tsx +5 -3
  51. package/src/routes/_authenticated/$sellerId/settings/general.tsx +6 -0
  52. package/src/routes/_authenticated/$sellerId/settings/profile.tsx +6 -0
  53. package/src/routes/_authenticated/$sellerId/settings/taxes.tsx +6 -0
  54. package/src/routes/_authenticated/$sellerId/settings.tsx +3 -7
  55. package/src/schemas/account.ts +1 -1
  56. package/src/tables/products.tsx +13 -6
  57. package/src/components/read-row.tsx +0 -16
  58. package/src/components/seller-business-card.tsx +0 -152
  59. package/src/pages/profile.tsx +0 -395
@@ -360,7 +360,10 @@
360
360
  "profile": "Profil",
361
361
  "settings": "Ustawienia",
362
362
  "sign_out": "Wyloguj się",
363
- "team": "Zespół"
363
+ "team": "Zespół",
364
+ "general": "Ogólne",
365
+ "taxes": "Podatki",
366
+ "store": "Sklep"
364
367
  },
365
368
  "onboarding": {
366
369
  "accept_terms": "Zaakceptuj regulamin",
@@ -593,7 +596,14 @@
593
596
  "not_found": "Nie znaleziono tej wypłaty.",
594
597
  "search_placeholder": "Szukaj po numerze referencyjnym",
595
598
  "subtitle": "Ile marketplace Ci już przekazał i co jest w drodze.",
596
- "title": "Wypłaty"
599
+ "title": "Wypłaty",
600
+ "schedule_intervals": {
601
+ "daily": "Codziennie",
602
+ "weekly": "Co tydzień",
603
+ "biweekly": "Co dwa tygodnie",
604
+ "monthly": "Co miesiąc",
605
+ "manual": "Gdy marketplace ją wyśle"
606
+ }
597
607
  },
598
608
  "policies": {
599
609
  "add": "Dodaj regulamin",
@@ -661,7 +671,8 @@
661
671
  "columns": {
662
672
  "name": "Produkt",
663
673
  "price": "Cena",
664
- "status": "Status"
674
+ "status": "Status",
675
+ "inventory": "Stan magazynowy"
665
676
  },
666
677
  "custom_fields": "Szczegóły produktu",
667
678
  "details": "Szczegóły",
@@ -735,48 +746,21 @@
735
746
  "digital_files_review_notice": "Dodanie lub zastąpienie pliku wysyła ten produkt ponownie do weryfikacji; do ponownego zatwierdzenia przez marketplace nie jest w sprzedaży."
736
747
  },
737
748
  "profile": {
738
- "about": "O sprzedawcy",
739
749
  "add_address": "Dodaj adres",
740
750
  "address_filled": "Dodano",
741
751
  "address_missing": "Nie dodano",
742
752
  "address_not_provided": "Brak adresu.",
743
- "at_a_glance": "W skrócie",
744
753
  "billing_address": "Adres rozliczeniowy",
745
- "billing_email": "E-mail do rozliczeń",
746
- "business_details": "Dane firmy",
747
- "contact_email": "E-mail kontaktowy",
748
754
  "edit": "Edytuj",
749
- "edit_title": "Edytuj swój profil",
750
- "joined": "Dołączono",
751
755
  "legal_name": "Nazwa prawna",
752
756
  "minimum_payout": "Minimalna wypłata",
753
- "name": "Nazwa",
754
- "no_about": "Nie masz jeszcze opisu.",
755
- "not_provided": "Nie podano",
756
- "on_holiday_notice": "Tryb urlopowy jest włączony, więc Twoje produkty są widoczne, ale nie można ich kupić.",
757
757
  "operator_managed": "Ustawia marketplace",
758
758
  "payout_schedule": "Harmonogram wypłat",
759
- "products_count": "Produkty",
760
759
  "registration_number": "Numer rejestrowy",
761
760
  "returns_address": "Adres zwrotów",
762
- "save": "Zapisz zmiany",
763
761
  "saved": "Profil zapisany",
764
- "saving": "Zapisywanie…",
765
- "section_contact": "Kontakt",
766
- "section_settlement": "Wypłaty i podatki",
767
- "section_standing": "Status współpracy",
768
762
  "select_tax_identifier_kind": "Wybierz lub wpisz rodzaj rejestracji",
769
- "status_help": {
770
- "approved": "Jesteś zatwierdzony i możesz sprzedawać na tym marketplace.",
771
- "canceled": "To konto sprzedawcy jest zamknięte.",
772
- "invited": "Masz zaproszenie. Dokończ konfigurację, aby złożyć zgłoszenie.",
773
- "onboarding": "Przejdź przez swoją listę zadań, a potem wyślij zgłoszenie do weryfikacji.",
774
- "pending": "Marketplace nie zajął się jeszcze Twoim zgłoszeniem.",
775
- "ready_for_review": "Marketplace weryfikuje Twoje zgłoszenie.",
776
- "rejected": "Twoje zgłoszenie nie zostało przyjęte. Skontaktuj się z marketplace’em, aby dowiedzieć się więcej.",
777
- "suspended": "Sprzedaż jest wstrzymana. Skontaktuj się z marketplace’em, aby dowiedzieć się więcej."
778
- },
779
- "subtitle": "Jak Twój sklep przedstawia Cię kupującym i jak marketplace może się z Tobą skontaktować.",
763
+ "subtitle": "Jak Twój sklep przedstawia Cię kupującym.",
780
764
  "tax_identifier_kind": "Rodzaj rejestracji",
781
765
  "tax_identifier_kinds": {
782
766
  "au_abn": "Australian Business Number",
@@ -786,13 +770,16 @@
786
770
  "us_ein": "US EIN"
787
771
  },
788
772
  "tax_remittance": "Podatek odprowadza",
789
- "team_count": "Członkowie zespołu",
790
773
  "vat_number": "Numer VAT",
791
774
  "vat_status": {
792
775
  "pending": "Sprawdzamy ten numer.",
793
776
  "unavailable": "Nie udało się połączyć z rejestrem — spróbujemy ponownie.",
794
777
  "unsupported": "Ten numer zapisujemy tak, jak go wpisano; nie możemy go sprawdzić automatycznie.",
795
778
  "unverified": "Nie udało się zweryfikować tego numeru."
779
+ },
780
+ "sections": {
781
+ "details": "Szczegóły",
782
+ "images": "Obrazy"
796
783
  }
797
784
  },
798
785
  "reset_password": {
@@ -853,5 +840,23 @@
853
840
  "member": "Członek zespołu"
854
841
  },
855
842
  "title": "Twój zespół"
843
+ },
844
+ "settings_general": {
845
+ "title": "Ogólne",
846
+ "description": "Jak marketplace się z Tobą kontaktuje, Twoja firma, adresy i tryb urlopowy.",
847
+ "sections": {
848
+ "contact": "Kontakt",
849
+ "business": "Firma",
850
+ "addresses": "Adresy",
851
+ "holiday": "Tryb urlopowy"
852
+ }
853
+ },
854
+ "taxes": {
855
+ "title": "Podatki",
856
+ "description": "Twoje rejestracje podatkowe i kto odprowadza podatek od Twojej sprzedaży.",
857
+ "remittance": {
858
+ "seller": "Ty",
859
+ "platform": "Marketplace"
860
+ }
856
861
  }
857
862
  }
@@ -360,7 +360,10 @@
360
360
  "delivery_methods": "Phương thức giao hàng",
361
361
  "package_types": "Các loại gói",
362
362
  "earnings": "Thu nhập",
363
- "payouts": "Xuất chi"
363
+ "payouts": "Xuất chi",
364
+ "general": "Chung",
365
+ "taxes": "Thuế",
366
+ "store": "Cửa hàng"
364
367
  },
365
368
  "onboarding": {
366
369
  "accept_terms": "Chấp nhận các điều khoản",
@@ -589,7 +592,14 @@
589
592
  "not_found": "Không thể tìm thấy khoản thanh toán này.",
590
593
  "search_placeholder": "Tìm kiếm theo tham chiếu",
591
594
  "subtitle": "Những gì thị trường đã gửi cho bạn và những gì đang trên đường đến.",
592
- "title": "Xuất chi"
595
+ "title": "Xuất chi",
596
+ "schedule_intervals": {
597
+ "daily": "Hằng ngày",
598
+ "weekly": "Hằng tuần",
599
+ "biweekly": "Hai tuần một lần",
600
+ "monthly": "Hằng tháng",
601
+ "manual": "Khi sàn gửi"
602
+ }
593
603
  },
594
604
  "policies": {
595
605
  "add": "Thêm chính sách",
@@ -655,7 +665,8 @@
655
665
  "columns": {
656
666
  "name": "Sản phẩm",
657
667
  "price": "Giá",
658
- "status": "Trạng thái"
668
+ "status": "Trạng thái",
669
+ "inventory": "Hàng tồn kho"
659
670
  },
660
671
  "custom_fields": "Chi tiết sản phẩm",
661
672
  "details": "Chi tiết",
@@ -729,48 +740,21 @@
729
740
  "digital_files_review_notice": "Việc thêm hoặc thay thế tệp sẽ gửi sản phẩm này trở lại để xem xét và sản phẩm sẽ được giảm giá cho đến khi được thị trường chấp thuận lại."
730
741
  },
731
742
  "profile": {
732
- "about": "Về",
733
743
  "add_address": "Thêm địa chỉ",
734
744
  "address_filled": "Đã thêm",
735
745
  "address_missing": "Chưa được thêm",
736
746
  "address_not_provided": "Chưa có địa chỉ.",
737
- "at_a_glance": "Trong nháy mắt",
738
747
  "billing_address": "Địa chỉ thanh toán",
739
- "billing_email": "Email thanh toán",
740
- "business_details": "Chi tiết doanh nghiệp",
741
- "contact_email": "Email liên hệ",
742
748
  "edit": "Chỉnh sửa",
743
- "edit_title": "Chỉnh sửa hồ sơ của bạn",
744
- "joined": "Đã tham gia",
745
749
  "legal_name": "Tên pháp lý",
746
750
  "minimum_payout": "Thanh toán tối thiểu",
747
- "name": "Tên",
748
- "no_about": "Bạn chưa viết mô tả.",
749
- "not_provided": "Không được cung cấp",
750
- "on_holiday_notice": "Chế độ nghỉ lễ đang bật nên sản phẩm của bạn có thể nhìn thấy nhưng không thể mua được.",
751
751
  "operator_managed": "Do sàn thương mại điện tử thiết lập",
752
752
  "payout_schedule": "Lịch thanh toán",
753
- "products_count": "Sản phẩm",
754
753
  "registration_number": "Số đăng ký",
755
754
  "returns_address": "Trả về địa chỉ",
756
- "save": "Lưu thay đổi",
757
755
  "saved": "Đã lưu hồ sơ",
758
- "saving": "Đang lưu…",
759
- "section_contact": "Liên hệ",
760
- "section_settlement": "Các khoản thanh toán và thuế",
761
- "section_standing": "Đứng",
762
756
  "select_tax_identifier_kind": "Chọn hoặc nhập loại đăng ký",
763
- "status_help": {
764
- "approved": "Bạn được chấp thuận và có thể bán trên thị trường này.",
765
- "canceled": "Tài khoản người bán này đã bị đóng.",
766
- "invited": "Bạn đã được mời. Hoàn tất việc thiết lập để áp dụng.",
767
- "onboarding": "Làm việc thông qua danh sách kiểm tra của bạn, sau đó gửi để xem xét.",
768
- "pending": "Thị trường vẫn chưa bắt đầu ứng dụng của bạn.",
769
- "ready_for_review": "Thị trường đang xem xét đơn đăng ký của bạn.",
770
- "rejected": "Đơn đăng ký của bạn không được chấp nhận. Hãy liên hệ với thị trường để tìm hiểu thêm.",
771
- "suspended": "Việc bán hàng bị tạm dừng. Hãy liên hệ với thị trường để tìm hiểu thêm."
772
- },
773
- "subtitle": "Cửa hàng trực tuyến của bạn giới thiệu bạn như thế nào và thị trường tiếp cận bạn như thế nào.",
757
+ "subtitle": "Cách cửa hàng giới thiệu bạn với người mua.",
774
758
  "tax_identifier_kind": "Loại đăng ký",
775
759
  "tax_identifier_kinds": {
776
760
  "au_abn": "Số doanh nghiệp Úc",
@@ -780,13 +764,16 @@
780
764
  "us_ein": "EIN Hoa Kỳ"
781
765
  },
782
766
  "tax_remittance": "Thuế được nộp bởi",
783
- "team_count": "Thành viên nhóm",
784
767
  "vat_number": "Số thuế GTGT",
785
768
  "vat_status": {
786
769
  "pending": "Chúng tôi đang kiểm tra con số này.",
787
770
  "unavailable": "Không thể truy cập cơ quan đăng ký - chúng tôi sẽ thử lại.",
788
771
  "unsupported": "Số này được ghi lại như đã nhập; chúng tôi không thể kiểm tra nó một cách tự động.",
789
772
  "unverified": "Con số này không thể được xác minh."
773
+ },
774
+ "sections": {
775
+ "details": "Thông tin",
776
+ "images": "Hình ảnh"
790
777
  }
791
778
  },
792
779
  "reset_password": {
@@ -847,5 +834,23 @@
847
834
  "member": "Thành viên"
848
835
  },
849
836
  "title": "Nhóm của bạn"
837
+ },
838
+ "settings_general": {
839
+ "title": "Chung",
840
+ "description": "Cách sàn liên hệ với bạn, doanh nghiệp, địa chỉ và chế độ nghỉ.",
841
+ "sections": {
842
+ "contact": "Liên hệ",
843
+ "business": "Doanh nghiệp",
844
+ "addresses": "Địa chỉ",
845
+ "holiday": "Chế độ nghỉ"
846
+ }
847
+ },
848
+ "taxes": {
849
+ "title": "Thuế",
850
+ "description": "Các đăng ký thuế của bạn và bên nộp thuế cho doanh số của bạn.",
851
+ "remittance": {
852
+ "seller": "Bạn",
853
+ "platform": "Sàn"
854
+ }
850
855
  }
851
856
  }
@@ -360,7 +360,10 @@
360
360
  "profile": "资料",
361
361
  "settings": "设置",
362
362
  "sign_out": "退出登录",
363
- "team": "团队"
363
+ "team": "团队",
364
+ "general": "常规",
365
+ "taxes": "税务",
366
+ "store": "店铺"
364
367
  },
365
368
  "onboarding": {
366
369
  "accept_terms": "接受条款",
@@ -587,7 +590,14 @@
587
590
  "not_found": "找不到该打款记录。",
588
591
  "search_placeholder": "按编号搜索",
589
592
  "subtitle": "市场已向你支付的金额,以及正在打款途中的金额。",
590
- "title": "打款"
593
+ "title": "打款",
594
+ "schedule_intervals": {
595
+ "daily": "每天",
596
+ "weekly": "每周",
597
+ "biweekly": "每两周",
598
+ "monthly": "每月",
599
+ "manual": "由平台发起时"
600
+ }
591
601
  },
592
602
  "policies": {
593
603
  "add": "添加政策",
@@ -652,7 +662,8 @@
652
662
  "columns": {
653
663
  "name": "商品",
654
664
  "price": "价格",
655
- "status": "状态"
665
+ "status": "状态",
666
+ "inventory": "库存"
656
667
  },
657
668
  "custom_fields": "商品详情",
658
669
  "details": "详情",
@@ -726,48 +737,21 @@
726
737
  "digital_files_review_notice": "添加或替换文件会将此商品重新送审,在平台再次批准前将暂停销售。"
727
738
  },
728
739
  "profile": {
729
- "about": "简介",
730
740
  "add_address": "添加地址",
731
741
  "address_filled": "已添加",
732
742
  "address_missing": "未添加",
733
743
  "address_not_provided": "尚无地址。",
734
- "at_a_glance": "概览",
735
744
  "billing_address": "账单地址",
736
- "billing_email": "账单邮箱",
737
- "business_details": "企业信息",
738
- "contact_email": "联系邮箱",
739
745
  "edit": "编辑",
740
- "edit_title": "编辑你的资料",
741
- "joined": "加入时间",
742
746
  "legal_name": "法定名称",
743
747
  "minimum_payout": "最低打款金额",
744
- "name": "名称",
745
- "no_about": "你还没有填写简介。",
746
- "not_provided": "未提供",
747
- "on_holiday_notice": "休假模式已开启,你的商品可见但无法购买。",
748
748
  "operator_managed": "由市场设置",
749
749
  "payout_schedule": "打款周期",
750
- "products_count": "商品",
751
750
  "registration_number": "注册号",
752
751
  "returns_address": "退货地址",
753
- "save": "保存修改",
754
752
  "saved": "资料已保存",
755
- "saving": "正在保存…",
756
- "section_contact": "联系方式",
757
- "section_settlement": "打款与税务",
758
- "section_standing": "账户状态",
759
753
  "select_tax_identifier_kind": "选择或输入登记类型",
760
- "status_help": {
761
- "approved": "你已获批准,可以在此市场销售。",
762
- "canceled": "此卖家账户已关闭。",
763
- "invited": "你已收到邀请。完成设置即可提交申请。",
764
- "onboarding": "逐项完成清单,然后提交审核。",
765
- "pending": "市场尚未开始处理你的申请。",
766
- "ready_for_review": "市场正在审核你的申请。",
767
- "rejected": "你的申请未被接受。请联系市场了解详情。",
768
- "suspended": "销售已暂停。请联系市场了解详情。"
769
- },
770
- "subtitle": "你的店铺如何展示你,以及市场如何联系你。",
754
+ "subtitle": "您的店铺如何向买家展示您。",
771
755
  "tax_identifier_kind": "登记类型",
772
756
  "tax_identifier_kinds": {
773
757
  "au_abn": "澳大利亚商业号码",
@@ -777,13 +761,16 @@
777
761
  "us_ein": "美国 EIN"
778
762
  },
779
763
  "tax_remittance": "税款申报方",
780
- "team_count": "团队成员",
781
764
  "vat_number": "增值税号",
782
765
  "vat_status": {
783
766
  "pending": "我们正在核验此号码。",
784
767
  "unavailable": "无法连接登记机构 — 我们会稍后重试。",
785
768
  "unsupported": "此号码按录入内容存档,我们无法自动核验。",
786
769
  "unverified": "此号码无法通过核验。"
770
+ },
771
+ "sections": {
772
+ "details": "详细信息",
773
+ "images": "图片"
787
774
  }
788
775
  },
789
776
  "reset_password": {
@@ -844,5 +831,23 @@
844
831
  "member": "成员"
845
832
  },
846
833
  "title": "你的团队"
834
+ },
835
+ "settings_general": {
836
+ "title": "常规",
837
+ "description": "平台如何联系您、您的企业信息、地址和休假模式。",
838
+ "sections": {
839
+ "contact": "联系方式",
840
+ "business": "企业信息",
841
+ "addresses": "地址",
842
+ "holiday": "休假模式"
843
+ }
844
+ },
845
+ "taxes": {
846
+ "title": "税务",
847
+ "description": "您的税务登记,以及由谁为您的销售缴纳税款。",
848
+ "remittance": {
849
+ "seller": "您",
850
+ "platform": "平台"
851
+ }
847
852
  }
848
853
  }
@@ -6,7 +6,6 @@ import {
6
6
  HomeIcon,
7
7
  PackageIcon,
8
8
  SettingsIcon,
9
- StoreIcon,
10
9
  TagIcon,
11
10
  } from '@spree/dashboard-ui/icons'
12
11
  import { OnboardingNavBadge } from '../components/onboarding-nav-badge'
@@ -84,15 +83,6 @@ nav.add({
84
83
  subject: 'seller_earnings',
85
84
  })
86
85
 
87
- nav.add({
88
- key: 'profile',
89
- label: i18n.t('nav.profile'),
90
- path: '/profile',
91
- icon: StoreIcon,
92
- position: 150,
93
- subject: 'seller_profile',
94
- })
95
-
96
86
  // Settings opens the landing page (and the secondary rail on wide viewports).
97
87
  // The entries inside it live in `nav/settings.ts`. Bottom section and gated
98
88
  // on there being something to see, exactly as the operator's dashboard does
@@ -1,7 +1,10 @@
1
1
  import { i18n, Subject, settingsNav } from '@spree/dashboard-core'
2
2
  import {
3
+ Building2Icon,
3
4
  PackageIcon,
5
+ PercentIcon,
4
6
  ScrollTextIcon,
7
+ StoreIcon,
5
8
  TruckIcon,
6
9
  UsersRoundIcon,
7
10
  WarehouseIcon,
@@ -15,6 +18,12 @@ import {
15
18
  // marketplace's, not a seller's; what belongs here is what a seller owns and
16
19
  // only they can answer.
17
20
 
21
+ settingsNav.addGroup({
22
+ key: 'store',
23
+ label: i18n.t('nav.store'),
24
+ position: 100,
25
+ })
26
+
18
27
  settingsNav.addGroup({
19
28
  key: 'fulfillment',
20
29
  labelKey: 'admin.settings_nav.groups.fulfillment',
@@ -112,3 +121,47 @@ settingsNav.add({
112
121
  subject: 'seller_profile',
113
122
  action: 'update',
114
123
  })
124
+
125
+ // What buyers see of the seller: name, description and images. After General,
126
+ // which is what a seller opens settings for most.
127
+ settingsNav.add({
128
+ key: 'settings.profile',
129
+ label: i18n.t('nav.profile'),
130
+ description: i18n.t('profile.subtitle'),
131
+ keywords: ['storefront', 'logo', 'cover', 'about', 'description', 'brand'],
132
+ path: '/profile',
133
+ icon: StoreIcon,
134
+ group: 'store',
135
+ position: 150,
136
+ subject: 'seller_profile',
137
+ action: 'update',
138
+ })
139
+
140
+ // How the marketplace reaches this seller, the business behind them, their
141
+ // addresses and holiday mode — everything about the seller that buyers never
142
+ // see. The public face stays on the profile page.
143
+ settingsNav.add({
144
+ key: 'settings.general',
145
+ label: i18n.t('nav.general'),
146
+ description: i18n.t('settings_general.description'),
147
+ keywords: ['contact', 'email', 'business', 'address', 'holiday', 'vacation', 'returns'],
148
+ path: '/general',
149
+ icon: Building2Icon,
150
+ group: 'store',
151
+ position: 100,
152
+ subject: 'seller_profile',
153
+ action: 'update',
154
+ })
155
+
156
+ settingsNav.add({
157
+ key: 'settings.taxes',
158
+ label: i18n.t('nav.taxes'),
159
+ description: i18n.t('taxes.description'),
160
+ keywords: ['vat', 'tax', 'registration', 'ein', 'remittance'],
161
+ path: '/taxes',
162
+ icon: PercentIcon,
163
+ group: 'store',
164
+ position: 200,
165
+ subject: 'seller_profile',
166
+ action: 'update',
167
+ })
@@ -5,7 +5,6 @@ import {
5
5
  defaultPreferences,
6
6
  filterPreferenceSchema,
7
7
  hasCurrencyAmount,
8
- PageHeader,
9
8
  PreferencesForm,
10
9
  type ResourceSearch,
11
10
  ResourceTable,
@@ -24,6 +23,12 @@ import {
24
23
  FieldError,
25
24
  FieldLabel,
26
25
  Input,
26
+ Item,
27
+ ItemActions,
28
+ ItemContent,
29
+ ItemDescription,
30
+ ItemFooter,
31
+ ItemTitle,
27
32
  RowActions,
28
33
  Select,
29
34
  SelectContent,
@@ -112,14 +117,8 @@ export function DeliveryMethodsPage({ search }: { search: ResourceSearch }) {
112
117
 
113
118
  return (
114
119
  <div className="flex flex-col gap-6">
115
- <PageHeader
116
- title={t('delivery_methods.title')}
117
- subtitle={t('delivery_methods.description')}
118
- sticky={false}
119
- />
120
-
121
120
  <ResourceTable<DeliveryMethod>
122
- hideHeader
121
+ description={t('delivery_methods.description')}
123
122
  tableKey="seller-delivery-methods"
124
123
  queryKey="seller-delivery-methods"
125
124
  queryFn={(params) => sellerClient().deliveryMethods.list(params)}
@@ -565,7 +564,7 @@ function DeliveryMethodSheet({
565
564
  <CardTitle>{t('delivery_methods.sections.conditions')}</CardTitle>
566
565
  </CardHeader>
567
566
  <CardContent className="flex flex-col gap-4">
568
- <p className="text-muted-foreground text-sm">
567
+ <p className="text-muted-foreground text-base">
569
568
  {t('delivery_methods.conditions.description')}
570
569
  </p>
571
570
 
@@ -573,54 +572,53 @@ function DeliveryMethodSheet({
573
572
  const definition = ruleTypes?.data.find((type) => type.type === rule.type)
574
573
 
575
574
  return (
576
- <div
577
- key={rule.id ?? `${rule.type}-${index}`}
578
- className="flex flex-col gap-3 rounded-lg border border-border-subtle p-3"
579
- >
580
- <div className="flex items-center justify-between gap-4">
581
- <div className="flex flex-col">
582
- <span className="font-medium text-sm">
583
- {typeLabel('delivery_method_rule', rule.type, definition?.name)}
584
- </span>
585
- {typeDescription(
586
- 'delivery_method_rule',
587
- rule.type,
588
- definition?.description,
589
- ) && (
590
- <span className="text-muted-foreground text-xs">
591
- {typeDescription(
592
- 'delivery_method_rule',
593
- rule.type,
594
- definition?.description,
595
- )}
596
- </span>
597
- )}
598
- </div>
575
+ <Item variant="outline" key={rule.id ?? `${rule.type}-${index}`}>
576
+ <ItemContent>
577
+ <ItemTitle>
578
+ {typeLabel('delivery_method_rule', rule.type, definition?.name)}
579
+ </ItemTitle>
580
+ {typeDescription(
581
+ 'delivery_method_rule',
582
+ rule.type,
583
+ definition?.description,
584
+ ) && (
585
+ <ItemDescription className="text-xs">
586
+ {typeDescription(
587
+ 'delivery_method_rule',
588
+ rule.type,
589
+ definition?.description,
590
+ )}
591
+ </ItemDescription>
592
+ )}
593
+ </ItemContent>
594
+ <ItemActions>
599
595
  <Button
600
596
  type="button"
601
597
  size="sm"
602
- variant="ghost"
598
+ variant="destructive-ghost"
603
599
  onClick={() => removeRule(index)}
604
600
  aria-label={t('delivery_methods.conditions.remove')}
605
601
  >
606
602
  <TrashIcon className="size-4" />
607
603
  </Button>
608
- </div>
609
-
610
- <PreferencesForm
611
- schema={renderableSchema(definition?.schema)}
612
- currencyOptions={currencyOptions}
613
- values={rule.preferences}
614
- onChange={(next) =>
615
- form.setValue(
616
- 'rules',
617
- rules.map((row, position) =>
618
- position === index ? { ...row, preferences: next } : row,
619
- ),
620
- )
621
- }
622
- />
623
- </div>
604
+ </ItemActions>
605
+
606
+ <ItemFooter className="flex-col items-stretch">
607
+ <PreferencesForm
608
+ schema={renderableSchema(definition?.schema)}
609
+ currencyOptions={currencyOptions}
610
+ values={rule.preferences}
611
+ onChange={(next) =>
612
+ form.setValue(
613
+ 'rules',
614
+ rules.map((row, position) =>
615
+ position === index ? { ...row, preferences: next } : row,
616
+ ),
617
+ )
618
+ }
619
+ />
620
+ </ItemFooter>
621
+ </Item>
624
622
  )
625
623
  })}
626
624
 
@@ -47,10 +47,10 @@ export function ForgotPasswordPage() {
47
47
  <div className="flex min-h-screen items-center justify-center p-6">
48
48
  <div className="w-full max-w-sm">
49
49
  <h1 className="font-medium text-xl">{t('forgot_password.sent_title')}</h1>
50
- <p className="mt-1 mb-6 text-muted-foreground text-sm">
50
+ <p className="mt-1 mb-6 text-muted-foreground text-base">
51
51
  {t('forgot_password.sent_subtitle')}
52
52
  </p>
53
- <Link to="/login" className="text-sm underline underline-offset-4">
53
+ <Link to="/login" className="text-base underline underline-offset-4">
54
54
  {t('forgot_password.back_to_login')}
55
55
  </Link>
56
56
  </div>
@@ -62,12 +62,12 @@ export function ForgotPasswordPage() {
62
62
  <div className="flex min-h-screen items-center justify-center p-6">
63
63
  <div className="w-full max-w-sm">
64
64
  <h1 className="font-medium text-xl">{t('forgot_password.title')}</h1>
65
- <p className="mt-1 mb-6 text-muted-foreground text-sm">{t('forgot_password.subtitle')}</p>
65
+ <p className="mt-1 mb-6 text-muted-foreground text-base">{t('forgot_password.subtitle')}</p>
66
66
 
67
67
  <form onSubmit={form.handleSubmit(onSubmit)}>
68
68
  <FieldGroup>
69
69
  {error && (
70
- <p className="text-destructive text-sm" role="alert">
70
+ <p className="text-destructive text-base" role="alert">
71
71
  {error}
72
72
  </p>
73
73
  )}
@@ -89,7 +89,7 @@ export function ForgotPasswordPage() {
89
89
  {isSubmitting ? t('forgot_password.submitting') : t('forgot_password.submit')}
90
90
  </Button>
91
91
 
92
- <Link to="/login" className="text-sm underline underline-offset-4">
92
+ <Link to="/login" className="text-base underline underline-offset-4">
93
93
  {t('forgot_password.back_to_login')}
94
94
  </Link>
95
95
  </FieldGroup>