fix auth
This commit is contained in:
@@ -25,6 +25,7 @@ import {
|
|||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Clipboard, Truck, Package } from "lucide-react";
|
import { Clipboard, Truck, Package } from "lucide-react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
interface Order {
|
interface Order {
|
||||||
orderId: string;
|
orderId: string;
|
||||||
@@ -49,6 +50,8 @@ export default function OrderDetailsPage() {
|
|||||||
const [productNames, setProductNames] = useState<Record<string, string>>({});
|
const [productNames, setProductNames] = useState<Record<string, string>>({});
|
||||||
const [isPaid, setIsPaid] = useState(false);
|
const [isPaid, setIsPaid] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const orderId = params?.id;
|
const orderId = params?.id;
|
||||||
|
|
||||||
@@ -110,6 +113,7 @@ export default function OrderDetailsPage() {
|
|||||||
setIsPaid(true);
|
setIsPaid(true);
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
router.push("/dashboard/orders");
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|||||||
@@ -1,8 +1,25 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
import Dashboard from "@/components/kokonutui/dashboard";
|
import Dashboard from "@/components/kokonutui/dashboard";
|
||||||
import { Package } from "lucide-react";
|
import { Package } from "lucide-react";
|
||||||
import OrderTable from "@/components/order-table"
|
import OrderTable from "@/components/order-table";
|
||||||
|
|
||||||
export default function OrdersPage() {
|
export default function OrdersPage() {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const authToken = document.cookie
|
||||||
|
.split("; ")
|
||||||
|
.find((row) => row.startsWith("Authorization="))
|
||||||
|
?.split("=")[1];
|
||||||
|
|
||||||
|
if (!authToken) {
|
||||||
|
router.push("/login");
|
||||||
|
}
|
||||||
|
}, [router]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dashboard>
|
<Dashboard>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
@@ -13,9 +30,8 @@ export default function OrdersPage() {
|
|||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ✅ Order Table Component */}
|
|
||||||
<OrderTable />
|
<OrderTable />
|
||||||
</div>
|
</div>
|
||||||
</Dashboard>
|
</Dashboard>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -33,10 +33,18 @@ export default function ProductsPage() {
|
|||||||
|
|
||||||
// Fetch products and categories
|
// Fetch products and categories
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const authToken = document.cookie
|
||||||
|
.split("; ")
|
||||||
|
.find((row) => row.startsWith("Authorization="))
|
||||||
|
?.split("=")[1];
|
||||||
|
|
||||||
|
if (!authToken) {
|
||||||
|
router.push("/login");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const fetchDataAsync = async () => {
|
const fetchDataAsync = async () => {
|
||||||
try {
|
try {
|
||||||
const authToken = document.cookie.split("Authorization=")[1];
|
|
||||||
|
|
||||||
const [fetchedProducts, fetchedCategories] = await Promise.all([
|
const [fetchedProducts, fetchedCategories] = await Promise.all([
|
||||||
fetchProductData(
|
fetchProductData(
|
||||||
`${process.env.NEXT_PUBLIC_API_URL}/products`,
|
`${process.env.NEXT_PUBLIC_API_URL}/products`,
|
||||||
|
|||||||
@@ -1,18 +1,11 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState, useEffect, ChangeEvent } from "react";
|
import { useState, useEffect, ChangeEvent } from "react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
import Layout from "@/components/kokonutui/layout";
|
import Layout from "@/components/kokonutui/layout";
|
||||||
import { Edit, Plus, Trash } from "lucide-react";
|
import { Edit, Plus, Trash } from "lucide-react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { ShippingModal } from "@/components/shipping-modal";
|
import { ShippingModal } from "@/components/shipping-modal";
|
||||||
import {
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow,
|
|
||||||
} from "@/components/ui/table";
|
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import {
|
import {
|
||||||
fetchShippingMethods,
|
fetchShippingMethods,
|
||||||
@@ -23,7 +16,7 @@ import {
|
|||||||
|
|
||||||
import { ShippingMethod, ShippingData } from "@/lib/types";
|
import { ShippingMethod, ShippingData } from "@/lib/types";
|
||||||
|
|
||||||
import { ShippingTable } from "@/components/shipping-table"
|
import { ShippingTable } from "@/components/shipping-table";
|
||||||
|
|
||||||
export default function ShippingPage() {
|
export default function ShippingPage() {
|
||||||
const [shippingMethods, setShippingMethods] = useState<ShippingMethod[]>([]);
|
const [shippingMethods, setShippingMethods] = useState<ShippingMethod[]>([]);
|
||||||
@@ -35,18 +28,32 @@ export default function ShippingPage() {
|
|||||||
const [modalOpen, setModalOpen] = useState<boolean>(false);
|
const [modalOpen, setModalOpen] = useState<boolean>(false);
|
||||||
const [editing, setEditing] = useState<boolean>(false);
|
const [editing, setEditing] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchShippingMethodsData = async () => {
|
const fetchShippingMethodsData = async () => {
|
||||||
try {
|
try {
|
||||||
const authToken = document.cookie.split("Authorization=")[1];
|
const authToken = document.cookie
|
||||||
const fetchedMethods: ShippingMethod[] = await fetchShippingMethods(authToken);
|
.split("; ")
|
||||||
|
.find((row) => row.startsWith("Authorization="))
|
||||||
// Ensure `_id` is always a string
|
?.split("=")[1];
|
||||||
const sanitizedMethods: ShippingMethod[] = fetchedMethods.map((method) => ({
|
|
||||||
...method,
|
if (!authToken) {
|
||||||
_id: method._id ?? "", // Default to empty string if undefined
|
router.push("/login");
|
||||||
}));
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchedMethods: ShippingMethod[] = await fetchShippingMethods(
|
||||||
|
authToken
|
||||||
|
);
|
||||||
|
|
||||||
|
const sanitizedMethods: ShippingMethod[] = fetchedMethods.map(
|
||||||
|
(method) => ({
|
||||||
|
...method,
|
||||||
|
_id: method._id ?? "",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
setShippingMethods(sanitizedMethods);
|
setShippingMethods(sanitizedMethods);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error loading shipping options:", error);
|
console.error("Error loading shipping options:", error);
|
||||||
@@ -54,17 +61,20 @@ export default function ShippingPage() {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchShippingMethodsData();
|
fetchShippingMethodsData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleAddShipping = async () => {
|
const handleAddShipping = async () => {
|
||||||
if (!newShipping.name || !newShipping.price) return;
|
if (!newShipping.name || !newShipping.price) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const authToken = document.cookie.split("Authorization=")[1];
|
const authToken = document.cookie.split("Authorization=")[1];
|
||||||
const updatedMethods: ShippingMethod[] = await addShippingMethod(authToken, newShipping);
|
const updatedMethods: ShippingMethod[] = await addShippingMethod(
|
||||||
|
authToken,
|
||||||
|
newShipping
|
||||||
|
);
|
||||||
|
|
||||||
setShippingMethods(updatedMethods);
|
setShippingMethods(updatedMethods);
|
||||||
setNewShipping({ name: "", price: 0 }); // No `_id` needed for new entry
|
setNewShipping({ name: "", price: 0 }); // No `_id` needed for new entry
|
||||||
setModalOpen(false);
|
setModalOpen(false);
|
||||||
@@ -72,16 +82,22 @@ export default function ShippingPage() {
|
|||||||
console.error("Error adding shipping method:", error);
|
console.error("Error adding shipping method:", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdateShipping = async () => {
|
const handleUpdateShipping = async () => {
|
||||||
if (!newShipping.name || !newShipping.price || !newShipping._id) return; // Ensure `_id` exists
|
if (!newShipping.name || !newShipping.price || !newShipping._id) return; // Ensure `_id` exists
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const authToken = document.cookie.split("Authorization=")[1];
|
const authToken = document.cookie.split("Authorization=")[1];
|
||||||
const updatedShipping: ShippingMethod = await updateShippingMethod(authToken, newShipping._id, newShipping);
|
const updatedShipping: ShippingMethod = await updateShippingMethod(
|
||||||
|
authToken,
|
||||||
|
newShipping._id,
|
||||||
|
newShipping
|
||||||
|
);
|
||||||
|
|
||||||
setShippingMethods((prevMethods) =>
|
setShippingMethods((prevMethods) =>
|
||||||
prevMethods.map((method) => (method._id === updatedShipping._id ? updatedShipping : method))
|
prevMethods.map((method) =>
|
||||||
|
method._id === updatedShipping._id ? updatedShipping : method
|
||||||
|
)
|
||||||
);
|
);
|
||||||
setNewShipping({ name: "", price: 0 });
|
setNewShipping({ name: "", price: 0 });
|
||||||
setEditing(false);
|
setEditing(false);
|
||||||
@@ -131,11 +147,11 @@ export default function ShippingPage() {
|
|||||||
|
|
||||||
{/* Shipping Methods Table */}
|
{/* Shipping Methods Table */}
|
||||||
<ShippingTable
|
<ShippingTable
|
||||||
shippingMethods={shippingMethods}
|
shippingMethods={shippingMethods}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
onEditShipping={handleEditShipping}
|
onEditShipping={handleEditShipping}
|
||||||
onDeleteShipping={handleDeleteShipping}
|
onDeleteShipping={handleDeleteShipping}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Shipping Modal */}
|
{/* Shipping Modal */}
|
||||||
|
|||||||
@@ -32,6 +32,16 @@ export default function StorefrontPage() {
|
|||||||
|
|
||||||
// ✅ Fetch Storefront Data
|
// ✅ Fetch Storefront Data
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const authToken = document.cookie
|
||||||
|
.split("; ")
|
||||||
|
.find((row) => row.startsWith("Authorization="))
|
||||||
|
?.split("=")[1];
|
||||||
|
|
||||||
|
if (!authToken) {
|
||||||
|
router.push("/login");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const fetchStorefront = async () => {
|
const fetchStorefront = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -48,7 +58,9 @@ export default function StorefrontPage() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// ✅ Handle Form Input Changes
|
// ✅ Handle Form Input Changes
|
||||||
const handleInputChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
const handleInputChange = (
|
||||||
|
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
|
||||||
|
) => {
|
||||||
setStorefront({ ...storefront, [e.target.name]: e.target.value });
|
setStorefront({ ...storefront, [e.target.name]: e.target.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -134,12 +146,20 @@ export default function StorefrontPage() {
|
|||||||
|
|
||||||
{/* Buttons */}
|
{/* Buttons */}
|
||||||
<div className="sticky bottom-6 mt-8 flex justify-between">
|
<div className="sticky bottom-6 mt-8 flex justify-between">
|
||||||
<Button onClick={() => setBroadcastOpen(true)} className="gap-2 bg-emerald-600 hover:bg-emerald-700 text-white">
|
<Button
|
||||||
|
onClick={() => setBroadcastOpen(true)}
|
||||||
|
className="gap-2 bg-emerald-600 hover:bg-emerald-700 text-white"
|
||||||
|
>
|
||||||
<Send className="h-5 w-5" /> Broadcast Message
|
<Send className="h-5 w-5" /> Broadcast Message
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button onClick={saveStorefront} disabled={saving} className="gap-2 bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-700 hover:to-indigo-700 text-white">
|
<Button
|
||||||
<Save className="h-5 w-5" /> {saving ? "Saving..." : "Save Configuration"}
|
onClick={saveStorefront}
|
||||||
|
disabled={saving}
|
||||||
|
className="gap-2 bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-700 hover:to-indigo-700 text-white"
|
||||||
|
>
|
||||||
|
<Save className="h-5 w-5" />{" "}
|
||||||
|
{saving ? "Saving..." : "Save Configuration"}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Package, Eye } from "lucide-react";
|
import { Eye } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { fetchWithAuthClient } from "@/lib/client-utils"; // ✅ Import client-safe API helper
|
import { fetchWithAuthClient } from "@/lib/client-utils"; // ✅ Import client-safe API helper
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
@@ -17,10 +17,9 @@ interface Order {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function OrderTable() {
|
export default function OrderTable() {
|
||||||
const [orders, setOrders] = useState<Order[]>([]);
|
const [orders, setOrders] = useState<Order[] | null>(null);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
|
||||||
// ✅ Fetch Orders on Load
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchOrders = async () => {
|
const fetchOrders = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -28,6 +27,7 @@ export default function OrderTable() {
|
|||||||
setOrders(data);
|
setOrders(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error("Failed to fetch orders.");
|
toast.error("Failed to fetch orders.");
|
||||||
|
console.error("Error fetching orders:", error);
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ export default function OrderTable() {
|
|||||||
<TableCell className="text-right">Loading...</TableCell>
|
<TableCell className="text-right">Loading...</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))
|
))
|
||||||
) : orders.length > 0 ? (
|
) : orders && orders.length > 0 ? (
|
||||||
orders.map((order) => (
|
orders.map((order) => (
|
||||||
<TableRow key={order._id} className="transition-colors hover:bg-gray-50 dark:hover:bg-zinc-800/70">
|
<TableRow key={order._id} className="transition-colors hover:bg-gray-50 dark:hover:bg-zinc-800/70">
|
||||||
<TableCell className="font-medium">{order._id.slice(-6)}</TableCell>
|
<TableCell className="font-medium">{order._id.slice(-6)}</TableCell>
|
||||||
@@ -77,7 +77,7 @@ export default function OrderTable() {
|
|||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={6} className="h-24 text-center">
|
<TableCell colSpan={5} className="h-24 text-center">
|
||||||
No orders found.
|
No orders found.
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
@@ -86,4 +86,4 @@ export default function OrderTable() {
|
|||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user