From f86789681798aab9f3481bdf3d16ac99a8ad73d2 Mon Sep 17 00:00:00 2001 From: Jelaletdin12 Date: Sat, 15 Nov 2025 16:14:01 +0500 Subject: [PATCH] connected api with profile, order --- app/[locale]/cart/page.tsx | 272 ++++++++------- app/[locale]/cart/ui/OrderSummary.tsx | 216 ------------ app/[locale]/cart/ui/types.ts | 119 ------- app/[locale]/category/[slug]/page.tsx | 2 +- app/[locale]/favorites/page.tsx | 2 +- app/[locale]/layout.tsx | 2 +- app/[locale]/me/page.tsx | 2 +- app/[locale]/orders/page.tsx | 2 +- app/[locale]/page.tsx | 34 +- app/[locale]/product/[slug]/page.tsx | 2 +- components/home/HomePage.tsx | 182 ---------- components/home/mockData.tsx | 56 --- components/layout/Header.tsx | 80 ++++- components/layout/ui/AuthDialog.tsx | 186 ++++++---- components/ui/dropdown-menu.tsx | 257 ++++++++++++++ context/AuthWrapper.tsx | 89 +++-- .../cart/components}/CartItemCard.tsx | 99 ++---- .../cart/components}/DeliveryTypeSelector.tsx | 2 +- features/cart/components/OrderSummary.tsx | 176 ++++++++++ .../cart/components}/PaymentTypeSelector.tsx | 0 features/cart/hooks/useAddresses.ts | 25 ++ {lib => features/cart}/hooks/useCart.ts | 28 +- .../cart}/hooks/usePaymentTypes.ts | 17 +- features/cart/types.ts | 171 +++++++++ .../category/components}/CategoryClient.tsx | 106 +++--- .../category/components}/CategoryContent.tsx | 0 .../category}/hooks/useCategories.ts | 5 +- .../category/types.ts | 0 .../favorites}/hooks/useFavorites.ts | 0 .../favorites/types.ts | 0 .../home/components}/Carousel.tsx | 0 .../home/components}/CategoryGrid.tsx | 64 ++-- features/home/components/HomePage.tsx | 118 +++++++ .../home/components}/ProductGrid.tsx | 83 ++--- features/home/hooks/useCollections.ts | 151 ++++++++ {lib => features/home}/hooks/useMedia.ts | 0 features/home/types.ts | 0 .../orders/components}/orders-content.tsx | 0 .../orders/components}/orders-page-client.tsx | 218 ++++++------ features/orders/hooks/useOrders.ts | 78 +++++ features/orders/types.ts | 59 ++++ .../components}/ProductPageContent.tsx | 4 +- .../products/components}/product-content.tsx | 0 .../products}/hooks/useProducts.ts | 0 features/products/types.ts | 0 .../profile/components}/client-page.tsx | 63 ++-- .../profile/components}/profile-content.tsx | 0 features/profile/hooks/useUserProfile.ts | 37 ++ features/profile/types.ts | 23 ++ features/profile/userStore.ts | 29 ++ i18n.ts => i18n/i18n.ts | 0 {messages => i18n/messages}/ru.json | 0 {messages => i18n/messages}/tm.json | 0 lib/config/api-endpoints.ts | 58 ---- lib/hooks/index.ts | 22 +- lib/hooks/useAuth.ts | 214 +++++------- lib/hooks/useCollections.ts | 108 ------ lib/hooks/useOpenStore.ts | 66 ++-- lib/hooks/useOrders.ts | 165 --------- lib/hooks/useSearch.ts | 48 +-- lib/hooks/useUserProfile.ts | 18 - lib/mock-server/axios-adapter.ts | 132 ------- lib/mock-server/data.ts | 95 ----- lib/mock-server/handlers.ts | 181 ---------- lib/types/api.ts | 327 +++++++++--------- middleware.ts | 2 +- next.config.ts | 2 +- package-lock.json | 88 +++++ package.json | 1 + public/styr.text | 101 ++++++ 70 files changed, 2370 insertions(+), 2317 deletions(-) delete mode 100644 app/[locale]/cart/ui/OrderSummary.tsx delete mode 100644 app/[locale]/cart/ui/types.ts delete mode 100644 components/home/HomePage.tsx delete mode 100644 components/home/mockData.tsx create mode 100644 components/ui/dropdown-menu.tsx rename {app/[locale]/cart/ui => features/cart/components}/CartItemCard.tsx (65%) rename {app/[locale]/cart/ui => features/cart/components}/DeliveryTypeSelector.tsx (96%) create mode 100644 features/cart/components/OrderSummary.tsx rename {app/[locale]/cart/ui => features/cart/components}/PaymentTypeSelector.tsx (100%) create mode 100644 features/cart/hooks/useAddresses.ts rename {lib => features/cart}/hooks/useCart.ts (89%) rename {lib => features/cart}/hooks/usePaymentTypes.ts (51%) create mode 100644 features/cart/types.ts rename {app/[locale]/category/[slug]/ui => features/category/components}/CategoryClient.tsx (89%) rename {app/[locale]/category/[slug]/ui => features/category/components}/CategoryContent.tsx (100%) rename {lib => features/category}/hooks/useCategories.ts (99%) rename lib/hooks/useAddresses.ts => features/category/types.ts (100%) rename {lib => features/favorites}/hooks/useFavorites.ts (100%) rename lib/hooks/useRegions.ts => features/favorites/types.ts (100%) rename {components/home => features/home/components}/Carousel.tsx (100%) rename {components/home => features/home/components}/CategoryGrid.tsx (58%) create mode 100644 features/home/components/HomePage.tsx rename {components/home => features/home/components}/ProductGrid.tsx (64%) create mode 100644 features/home/hooks/useCollections.ts rename {lib => features/home}/hooks/useMedia.ts (100%) create mode 100644 features/home/types.ts rename {app/[locale]/orders => features/orders/components}/orders-content.tsx (100%) rename {app/[locale]/orders => features/orders/components}/orders-page-client.tsx (63%) create mode 100644 features/orders/hooks/useOrders.ts create mode 100644 features/orders/types.ts rename {app/[locale]/product/[slug] => features/products/components}/ProductPageContent.tsx (99%) rename {app/[locale]/product/[slug] => features/products/components}/product-content.tsx (100%) rename {lib => features/products}/hooks/useProducts.ts (100%) create mode 100644 features/products/types.ts rename {app/[locale]/me => features/profile/components}/client-page.tsx (67%) rename {app/[locale]/me => features/profile/components}/profile-content.tsx (100%) create mode 100644 features/profile/hooks/useUserProfile.ts create mode 100644 features/profile/types.ts create mode 100644 features/profile/userStore.ts rename i18n.ts => i18n/i18n.ts (100%) rename {messages => i18n/messages}/ru.json (100%) rename {messages => i18n/messages}/tm.json (100%) delete mode 100644 lib/config/api-endpoints.ts delete mode 100644 lib/hooks/useCollections.ts delete mode 100644 lib/hooks/useOrders.ts delete mode 100644 lib/hooks/useUserProfile.ts delete mode 100644 lib/mock-server/axios-adapter.ts delete mode 100644 lib/mock-server/data.ts delete mode 100644 lib/mock-server/handlers.ts create mode 100644 public/styr.text diff --git a/app/[locale]/cart/page.tsx b/app/[locale]/cart/page.tsx index 009dfe3..3b9ae8d 100644 --- a/app/[locale]/cart/page.tsx +++ b/app/[locale]/cart/page.tsx @@ -1,53 +1,79 @@ -"use client" -import { useState, useEffect } from "react" -import { Card } from "@/components/ui/card" -import { Separator } from "@/components/ui/separator" -import CartItemCard from "./ui/CartItemCard" -import OrderSummary from "./ui/OrderSummary" -import { useCart, useCreateOrder, useRegions, useAddresses, usePaymentTypes } from "@/lib/hooks" -import { useTranslations } from "next-intl" -import { useRouter } from "next/navigation" -import type { DeliveryType, PaymentTypeOption } from "./ui/types" +"use client"; +import { useState, useEffect } from "react"; +import { Card } from "@/components/ui/card"; +import { Separator } from "@/components/ui/separator"; +import CartItemCard from "../../../features/cart/components/CartItemCard"; +import OrderSummary from "../../../features/cart/components/OrderSummary"; +import { + useCart, + useCreateOrder, + useRegions, + usePaymentTypes, +} from "@/lib/hooks"; +import { userStore } from "@/features/profile/userStore"; +import { useTranslations } from "next-intl"; +import { useRouter } from "next/navigation"; +import type { DeliveryType, PaymentType } from "../../../features/cart/types"; export default function CartPage() { - const [isClient, setIsClient] = useState(false) - const [paymentType, setPaymentType] = useState(null) - const [deliveryType, setDeliveryType] = useState("SELECTED_DELIVERY") - const [selectedRegion, setSelectedRegion] = useState(null) - const [selectedAddress, setSelectedAddress] = useState("") - const [note, setNote] = useState("") - const router = useRouter() + const [isClient, setIsClient] = useState(false); + const [paymentType, setPaymentType] = useState(null); + const [deliveryType, setDeliveryType] = useState("SELECTED_DELIVERY"); + const [selectedRegion, setSelectedRegion] = useState(""); + const [selectedProvince, setSelectedProvince] = useState(null); + const [note, setNote] = useState(""); + const router = useRouter(); - const t = useTranslations() + const t = useTranslations(); - // useCart dönen data yapısı: { message: "success", data: [...] } - const { data: cartResponse, isLoading, isError } = useCart() - const { data: regions = [] } = useRegions() - const { data: addresses = [] } = useAddresses() - const { data: paymentTypes = [] } = usePaymentTypes() - const { mutate: createOrder, isPending: isCreatingOrder } = useCreateOrder() + const { data: cartResponse, isLoading, isError } = useCart(); + const { data: provinces = [] } = useRegions(); + const { data: paymentTypes = [] } = usePaymentTypes(); + const { mutate: createOrder, isPending: isCreatingOrder } = useCreateOrder(); - // Cart items'ı doğru şekilde al - const cartItems = cartResponse?.data || [] + const cartItems = cartResponse?.data || []; useEffect(() => { - setIsClient(true) - }, []) + setIsClient(true); + }, []); + + const regionGroups = provinces.reduce((acc, province) => { + if (!acc[province.region]) { + acc[province.region] = []; + } + acc[province.region].push(province); + return acc; + }, {} as Record); + + const availableRegions = Object.keys(regionGroups); const handleDeliveryTypeChange = (type: DeliveryType) => { - setDeliveryType(type) - setSelectedAddress("") - } + setDeliveryType(type); + setSelectedProvince(null); + }; const handleCompleteOrder = () => { - if (!selectedRegion || !selectedAddress || !paymentType) { - console.warn("Missing required fields for order") - return + if (!selectedRegion || !selectedProvince || !paymentType) { + console.warn("Missing required fields for order"); + return; + } + + const selectedProvinceData = provinces.find((p) => p.id === selectedProvince); + if (!selectedProvinceData) return; + + // Kullanıcı bilgilerini store'dan al + const orderData = userStore.getOrderData(); + if (!orderData) { + console.error("User data not found"); + router.push("/login"); + return; } createOrder( { - customer_address: selectedAddress, + customer_name: orderData.customer_name, + customer_phone: orderData.customer_phone, + customer_address: selectedProvinceData.name, shipping_method: deliveryType === "PICK_UP" ? "pickup" : "standart", payment_type_id: paymentType.id, region: selectedRegion, @@ -55,30 +81,30 @@ export default function CartPage() { }, { onSuccess: () => { - router.push(`/orders`) + router.push(`/orders`); }, - }, - ) - } + } + ); + }; - if (!isClient) return null + if (!isClient) return null; if (isLoading) { return (

{t("loading")}

- ) + ); } if (isError || cartItems.length === 0) { return (

- {t("emptyCart") || "Your cart is empty"} + {t("emptyCart")}

- ) + ); } const translations = { @@ -100,105 +126,108 @@ export default function CartPage() { placeOrder: t("order"), emptyCart: t("cart_empty"), map: t("address"), - } + }; - // Group items by seller (from channel) - const itemsBySeller = cartItems.reduce( - (acc, item) => { - const sellerId = item.product.channel?.[0]?.id || 0 - const sellerName = item.product.channel?.[0]?.name || "Unknown Seller" - - if (!acc[sellerId]) { - acc[sellerId] = { - seller: { id: sellerId, name: sellerName }, - items: [] - } - } - acc[sellerId].items.push(item) - return acc - }, - {} as Record - ) + const itemsBySeller = cartItems.reduce((acc, item) => { + const sellerId = item.product.channel?.[0]?.id || 0; + const sellerName = item.product.channel?.[0]?.name || "Unknown Seller"; + + if (!acc[sellerId]) { + acc[sellerId] = { + seller: { id: sellerId, name: sellerName }, + items: [], + }; + } + acc[sellerId].items.push(item); + return acc; + }, {} as Record); - // Calculate total const totalAmount = cartItems.reduce((sum, item) => { - const price = parseFloat(item.product.price_amount || "0") - return sum + (price * item.product_quantity) - }, 0) + const price = parseFloat(item.product.price_amount || "0"); + return sum + price * item.product_quantity; + }, 0); return (

{translations.cart}

- {/* Cart Items Section */}
- {/* Sellers */} - {Object.entries(itemsBySeller).map(([sellerId, { seller, items }]) => ( -
-

{seller.name}

-
- {items.map((item) => { - const price = parseFloat(item.product.price_amount || "0") - const quantity = item.product_quantity - const total = price * quantity - - return ( - m.images_800x800 || m.thumbnail) || [] - } - }} - translations={translations} - /> - ) - })} + {Object.entries(itemsBySeller).map( + ([sellerId, { seller, items }]) => ( +
+

{seller.name}

+
+ {items.map((item) => { + const price = parseFloat(item.product.price_amount || "0"); + const quantity = item.product_quantity; + const total = price * quantity; + + return ( + m.images_800x800 || m.thumbnail + ) || [], + }, + }} + translations={translations} + /> + ); + })} +
+ {Object.entries(itemsBySeller).length > 1 && ( + + )}
- {Object.entries(itemsBySeller).length > 1 && } -
- ))} + ) + )}
- {/* Order Summary Sidebar */} ({ + items: cartItems.map((item) => ({ ...item, quantity: item.product_quantity, price: parseFloat(item.product.price_amount || "0"), - total: parseFloat(item.product.price_amount || "0") * item.product_quantity, - seller: { - id: item.product.channel?.[0]?.id || 0, - name: item.product.channel?.[0]?.name || "Unknown" - } + total: + parseFloat(item.product.price_amount || "0") * + item.product_quantity, + seller: { + id: item.product.channel?.[0]?.id || 0, + name: item.product.channel?.[0]?.name || "Unknown", + }, })), billing: { body: [ - { - title: t("goods"), - value: `${totalAmount.toFixed(2)} TMT` - } + { + title: t("goods"), + value: `${totalAmount.toFixed(2)} TMT`, + }, ], - footer: { - title: t("total"), - value: `${totalAmount.toFixed(2)} TMT` + footer: { + title: t("total"), + value: `${totalAmount.toFixed(2)} TMT`, }, }, }} @@ -206,21 +235,20 @@ export default function CartPage() { paymentType={paymentType} deliveryType={deliveryType} selectedRegion={selectedRegion} - selectedAddress={selectedAddress} + selectedProvince={selectedProvince} note={note} - regions={regions} - addresses={addresses} + regionGroups={regionGroups} + availableRegions={availableRegions} paymentTypes={paymentTypes} onPaymentTypeChange={setPaymentType} onDeliveryTypeChange={handleDeliveryTypeChange} onRegionChange={setSelectedRegion} - onAddressChange={setSelectedAddress} + onProvinceChange={setSelectedProvince} onNoteChange={setNote} - onMapOpen={() => {}} onCompleteOrder={handleCompleteOrder} isLoading={isCreatingOrder} />
- ) + ); } \ No newline at end of file diff --git a/app/[locale]/cart/ui/OrderSummary.tsx b/app/[locale]/cart/ui/OrderSummary.tsx deleted file mode 100644 index cb083d7..0000000 --- a/app/[locale]/cart/ui/OrderSummary.tsx +++ /dev/null @@ -1,216 +0,0 @@ -"use client" -import { MapPin } from "lucide-react" -import { Button } from "@/components/ui/button" -import { Card } from "@/components/ui/card" -import { Label } from "@/components/ui/label" -import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" -import { Textarea } from "@/components/ui/textarea" -import { Separator } from "@/components/ui/separator" -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue -} from "@/components/ui/select" -import DeliveryTypeSelector from "./DeliveryTypeSelector" -import type { - Order, - Region, - Address, - DeliveryType, - CartTranslations, - PaymentTypeOption -} from "./types" - -interface OrderSummaryProps { - order: Order - translations: CartTranslations - paymentType: PaymentTypeOption | null - deliveryType: DeliveryType - selectedRegion: string | null - selectedAddress: string - note: string - regions: Region[] - addresses: Address[] - paymentTypes: PaymentTypeOption[] - onPaymentTypeChange: (type: PaymentTypeOption) => void - onDeliveryTypeChange: (type: DeliveryType) => void - onRegionChange: (regionCode: string) => void - onAddressChange: (address: string) => void - onNoteChange: (note: string) => void - onMapOpen: () => void - onCompleteOrder: () => void - isLoading: boolean -} - -export default function OrderSummary({ - order, - translations: t, - paymentType, - deliveryType, - selectedRegion, - selectedAddress, - note, - regions, - addresses, - paymentTypes, - onPaymentTypeChange, - onDeliveryTypeChange, - onRegionChange, - onAddressChange, - onNoteChange, - onMapOpen, - onCompleteOrder, - isLoading, -}: OrderSummaryProps) { - // Filter addresses based on selected region - const filteredAddresses = selectedRegion - ? addresses.filter((addr) => { - const region = regions.find((r) => r.code === selectedRegion) - return region && addr.region_id === region.id - }) - : [] - - // Validate form completion - const isFormValid = selectedRegion && selectedAddress && paymentType - - return ( - - {/* Payment Type Selection */} -
-

{t.paymentType}

-
- {paymentTypes.map((type) => ( - onPaymentTypeChange(type)} - > -
- {type.name} -
-
- ))} -
-
- - {/* Delivery Type Selection */} - - - {/* Region Selection */} -
- - - {regions.map((region) => ( -
- - -
- ))} -
-
- - {/* Address Selection (only show when region is selected) */} - {selectedRegion && filteredAddresses.length > 0 && ( -
- -
- - -
-
- )} - - {/* Note Input */} -
- -