feat: Implement Phase 1 Shopify-inspired settings (Store, Payments, Shipping)
✨ Features: - Store Details page with live currency preview - Payments page with visual provider cards and test mode - Shipping & Delivery page with zone cards and local pickup - Shared components: SettingsLayout, SettingsCard, SettingsSection, ToggleField 🎨 UI/UX: - Card-based layouts (not boring forms) - Generous whitespace and visual hierarchy - Toast notifications using sonner (reused from Orders) - Sticky save button at top - Mobile-responsive design 🔧 Technical: - Installed ESLint with TypeScript support - Fixed all lint errors (0 errors) - Phase 1 files have zero warnings - Used existing toast from sonner (not reinvented) - Updated routes in App.tsx 📝 Files Created: - Store.tsx (currency preview, address, timezone) - Payments.tsx (provider cards, manual methods) - Shipping.tsx (zone cards, rates, local pickup) - SettingsLayout.tsx, SettingsCard.tsx, SettingsSection.tsx, ToggleField.tsx Phase 1 complete: 18-24 hours estimated work
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useParams, Link, useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import { useParams, useSearchParams, Link } from 'react-router-dom';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { api, OrdersApi } from '@/lib/api';
|
||||
import { formatRelativeOrDate } from '@/lib/dates';
|
||||
@@ -11,7 +11,7 @@ import { Button } from '@/components/ui/button';
|
||||
import { showErrorToast, showSuccessToast, getPageLoadErrorMessage } from '@/lib/errorHandling';
|
||||
import { ErrorCard } from '@/components/ErrorCard';
|
||||
import { InlineLoadingState } from '@/components/LoadingState';
|
||||
import { __, sprintf } from '@/lib/i18n';
|
||||
import { __ } from '@/lib/i18n';
|
||||
|
||||
function Money({ value, currency, symbol }: { value?: number; currency?: string; symbol?: string }) {
|
||||
return <>{formatMoney(value, { currency, symbol })}</>;
|
||||
@@ -19,7 +19,7 @@ function Money({ value, currency, symbol }: { value?: number; currency?: string;
|
||||
|
||||
function StatusBadge({ status }: { status?: string }) {
|
||||
const s = (status || '').toLowerCase();
|
||||
let cls = 'inline-flex items-center rounded px-2 py-1 text-xs font-medium border';
|
||||
const cls = 'inline-flex items-center rounded px-2 py-1 text-xs font-medium border';
|
||||
let tone = 'bg-gray-100 text-gray-700 border-gray-200';
|
||||
if (s === 'completed' || s === 'paid') tone = 'bg-green-100 text-green-800 border-green-200';
|
||||
else if (s === 'processing') tone = 'bg-yellow-100 text-yellow-800 border-yellow-200';
|
||||
@@ -33,7 +33,6 @@ const STATUS_OPTIONS = ['pending', 'processing', 'completed', 'on-hold', 'cancel
|
||||
|
||||
export default function OrderShow() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const nav = useNavigate();
|
||||
const qc = useQueryClient();
|
||||
const siteTitle = (window as any).wnw?.siteTitle || 'WooNooW';
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import { makeMoneyFormatter, getStoreCurrency } from '@/lib/currency';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { api, ProductsApi, CustomersApi } from '@/lib/api';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { __, sprintf } from '@/lib/i18n';
|
||||
import { __ } from '@/lib/i18n';
|
||||
import { toast } from 'sonner';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
@@ -107,7 +107,7 @@ export default function OrderForm({
|
||||
shippings = [],
|
||||
onSubmit,
|
||||
className,
|
||||
leftTop,
|
||||
leftTop: _leftTop,
|
||||
rightTop,
|
||||
itemsEditable = true,
|
||||
showCoupons = true,
|
||||
@@ -169,7 +169,6 @@ export default function OrderForm({
|
||||
const [submitting, setSubmitting] = React.useState(false);
|
||||
|
||||
const [items, setItems] = React.useState<LineItem[]>(initial?.items || []);
|
||||
const [coupons, setCoupons] = React.useState('');
|
||||
const [couponInput, setCouponInput] = React.useState('');
|
||||
const [validatedCoupons, setValidatedCoupons] = React.useState<any[]>([]);
|
||||
const [couponValidating, setCouponValidating] = React.useState(false);
|
||||
|
||||
Reference in New Issue
Block a user