+
Expiration Date:
- {bill.expirationDate}
+ {bill.expiration_date}
-
+
Tour Invoice Amount:
- ${bill.amount.toFixed(2)}
+ ${bill.amount}
diff --git a/src/app/[locale]/(account-pages)/bills/[slug]/page.tsx b/src/app/[locale]/(account-pages)/bills/[slug]/page.tsx
index 6d244d7..9f6abf9 100644
--- a/src/app/[locale]/(account-pages)/bills/[slug]/page.tsx
+++ b/src/app/[locale]/(account-pages)/bills/[slug]/page.tsx
@@ -1,15 +1,24 @@
-// BillDetailCard.tsx
-import React from "react";
+import React, { useState } from "react";
+import axiosInstance from "@/components/api/axios";
import ButtonPrimary from "@/shared/ButtonPrimary";
import Button from "@/shared/Button";
-
-
-export type BillStatus = "Awaiting Payment" | "Approved" | "Rejected" | "Pending";
+import Input from "@/shared/Input";
+import { useUserContext } from "@/components/contexts/userContext";
+import getImageURL from "@/components/api/getImageURL";
+import { toast, ToastContainer } from "react-toastify";
+import Image from "next/image";
+
+export type BillStatus =
+ | "awaiting_payment"
+ | "approved"
+ | "rejected"
+ | "pending";
export interface Bill {
+ id: number;
title: string;
- issuedDate: string;
- expirationDate: string;
+ created_at: string;
+ expiration_date: string;
amount: number;
status: BillStatus;
passengers: { type: string; count: number }[];
@@ -20,29 +29,84 @@ export interface Bill {
size: string;
src: string;
};
+ detail_service: {
+ passenger_counts: { adults: string; children: string; infants: string };
+ };
+ transaction_receipt: string;
+ card_number: string | number;
}
-
-
interface BillDetailCardProps {
bill: Bill;
}
-const statusStyles: { [key in BillStatus]: string } = {
- "Awaiting Payment": "bg-yellow-200 text-yellow-700",
- Approved: "bg-green-200 text-green-700",
- Rejected: "bg-red-200 text-red-700",
- Pending: "bg-blue-200 text-blue-700",
+const statusStyles: { [key in BillStatus]: JSX.Element } = {
+ awaiting_payment: (
+
+ Awaiting Payment
+
+ ),
+ approved: (
+
+ Approved
+
+ ),
+ rejected: (
+
+ Rejected
+
+ ),
+ pending: (
+
+ Pending
+
+ ),
};
const BillDetailCard: React.FC
= ({ bill }) => {
+ const [uploadedFile, setUploadedFile] = useState(null);
+ const [loadingUpload, setLoadingUpload] = useState(false);
+ const [loading, setLoading] = useState(false);
+ const { user } = useUserContext();
+ const handleFileChange = async (e: React.ChangeEvent) => {
+ setLoadingUpload(true);
+ const file = e.target.files?.[0];
+ if (file) {
+ const uploadedFile = await getImageURL(file);
+ setUploadedFile(uploadedFile.url);
+ setLoadingUpload(false);
+ }
+ };
+
+ const handleSubmit = () => {
+ setLoading(true);
+ if (uploadedFile) {
+ const formData = new FormData();
+ formData.append("transaction_receipt", uploadedFile);
+ axiosInstance
+ .patch(`/api/factors/update/${bill.id}/`, formData, {
+ headers: {
+ Authorization: `token ${user.token}`,
+ },
+ })
+ .then(() => {
+ toast.success("Transaction receipt updated successfully");
+ setLoading(false);
+ })
+ .catch(() => {
+ toast.error("Error updating transaction receipt");
+ setLoading(false);
+ });
+ } else {
+ console.log("No new file to upload");
+ }
+ };
+
return (
-
+
{bill.title}
-
- {bill.status}
-
+ {statusStyles[bill.status]}
{bill.message && (
@@ -52,23 +116,33 @@ const BillDetailCard: React.FC
= ({ bill }) => {
)}
-
+
Issued Date:
- {bill.issuedDate}
+ {bill.created_at}
Expiration Date:
- {bill.expirationDate}
+ {bill.expiration_date}
Number of Passengers
- {bill.passengers.map((p, index) => (
-
- #{p.count} ({p.type})
-
- ))}
+
+
+ # {bill.detail_service.passenger_counts.adults} (Adults)
+
+
+
+
+ # {bill.detail_service.passenger_counts.children} (Children)
+
+
+
+
+ # {bill.detail_service.passenger_counts.infants} (Infants)
+
+
@@ -78,8 +152,10 @@ const BillDetailCard: React.FC
= ({ bill }) => {
Account Number
-
-
{bill.accountNumber}
+
+
+ {bill.card_number}
+
@@ -87,25 +163,60 @@ const BillDetailCard: React.FC
= ({ bill }) => {
{bill.uploadedImage ? (
Uploaded Image
-
+
{bill.uploadedImage.name}
- {bill.uploadedImage.size}
+
+ {bill.uploadedImage.size}
+
) : (
-
-
-
-
No File Selected
+
+
+
+ {loadingUpload &&
Loading ...
}
+ {bill.transaction_receipt ? (
+
+
+
+ ) : (
+
+ No File Selected
+
+ )}
)}
- Submit
+
+ Submit
+
+
);
};
diff --git a/src/app/[locale]/(account-pages)/bills/page.tsx b/src/app/[locale]/(account-pages)/bills/page.tsx
index 80d0a8c..83a64aa 100644
--- a/src/app/[locale]/(account-pages)/bills/page.tsx
+++ b/src/app/[locale]/(account-pages)/bills/page.tsx
@@ -1,12 +1,18 @@
// BillsPage.tsx
-"use client"
-import React, { useState } from "react";
+"use client";
+import React, { useEffect, useState } from "react";
import BillCard from "./BillCard";
import BillDetailCard from "./[slug]/page";
-
+import axiosInstance from "@/components/api/axios";
+import { useUserContext } from "@/components/contexts/userContext";
+import { headers } from "next/dist/client/components/headers";
// types.ts
-export type BillStatus = "Awaiting Payment" | "Approved" | "Rejected" | "Pending";
+export type BillStatus =
+ | "Awaiting Payment"
+ | "Approved"
+ | "Rejected"
+ | "Pending";
export interface Bill {
title: string;
@@ -14,68 +20,68 @@ export interface Bill {
expirationDate: string;
amount: number;
status: BillStatus;
- passengers : {}
- accountNumber: string,
- message? : string
-
+ passengers: {};
+ accountNumber: string;
+ message?: string;
}
-
-const bills: Bill[] = [
- {
- title: "Karbala Tour Bill",
- issuedDate: "12 Jan 2023",
- expirationDate: "10 Jan 2023",
- amount: 960,
- status: "Awaiting Payment",
- passengers: [
- { type: "Adult", count: 3 },
- { type: "Child", count: 2 },
- { type: "Infant", count: 1 },
- ],
- accountNumber: "123-456-7890-0123",
- },
- {
- title: "SIM Card Bill",
- issuedDate: "12 Jan 2023",
- expirationDate: "10 Jan 2023",
- amount: 960,
- status: "Approved",
- passengers: [
- { type: "Adult", count: 2 },
- { type: "Child", count: 1 },
- ],
- accountNumber: "987-654-3210-0123",
- },
- {
- title: "Shop Bill",
- issuedDate: "12 Jan 2023",
- expirationDate: "10 Jan 2023",
- amount: 960,
- status: "Rejected",
- passengers: [
- { type: "Adult", count: 1 },
- ],
- accountNumber: "456-789-0123-4567",
- message:
- "The uploaded image does not meet the required quality standards. Please use a higher-resolution photo.",
- },
- {
- title: "Tasrif Bill",
- issuedDate: "12 Jan 2023",
- expirationDate: "10 Jan 2023",
- amount: 960,
- status: "Pending",
- passengers: [
- { type: "Adult", count: 3 },
- { type: "Child", count: 2 },
- ],
- accountNumber: "321-654-9870-1234",
- },
-];
+// const bills: Bill[] = [
+// {
+// title: "Karbala Tour Bill",
+// issuedDate: "12 Jan 2023",
+// expirationDate: "10 Jan 2023",
+// amount: 960,
+// status: "Awaiting Payment",
+// passengers: [
+// { type: "Adult", count: 3 },
+// { type: "Child", count: 2 },
+// { type: "Infant", count: 1 },
+// ],
+// accountNumber: "123-456-7890-0123",
+// },
+// {
+// title: "SIM Card Bill",
+// issuedDate: "12 Jan 2023",
+// expirationDate: "10 Jan 2023",
+// amount: 960,
+// status: "Approved",
+// passengers: [
+// { type: "Adult", count: 2 },
+// { type: "Child", count: 1 },
+// ],
+// accountNumber: "987-654-3210-0123",
+// },
+// {
+// title: "Shop Bill",
+// issuedDate: "12 Jan 2023",
+// expirationDate: "10 Jan 2023",
+// amount: 960,
+// status: "Rejected",
+// passengers: [
+// { type: "Adult", count: 1 },
+// ],
+// accountNumber: "456-789-0123-4567",
+// message:
+// "The uploaded image does not meet the required quality standards. Please use a higher-resolution photo.",
+// },
+// {
+// title: "Tasrif Bill",
+// issuedDate: "12 Jan 2023",
+// expirationDate: "10 Jan 2023",
+// amount: 960,
+// status: "Pending",
+// passengers: [
+// { type: "Adult", count: 3 },
+// { type: "Child", count: 2 },
+// ],
+// accountNumber: "321-654-9870-1234",
+// },
+// ];
const BillsPage: React.FC = () => {
+ const [bills, setBills] = useState([]);
const [selectedBill, setSelectedBill] = useState(null);
+ const { user } = useUserContext();
const handleViewDetail = (bill: Bill) => {
setSelectedBill(bill);
@@ -84,9 +90,23 @@ const BillsPage: React.FC = () => {
const handleBackToList = () => {
setSelectedBill(null);
};
+ useEffect(() => {
+ axiosInstance("/api/factors/list/", {
+ headers: {
+ Authorization: `token ${user.token}`,
+ },
+ })
+ .then((response) => {
+ console.log(response);
+ setBills(response.data.results);
+ })
+ .catch((error) => {
+ console.log(error.message);
+ });
+ }, []);
return (
-
+
{selectedBill ? (