solved build errors
This commit is contained in:
parent
7ddb3ec744
commit
ea738e676d
@ -1,12 +1,13 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
import { Suspense } from 'react';
|
||||||
import { useSearchParams } from 'next/navigation';
|
import { useSearchParams } from 'next/navigation';
|
||||||
import { useEffect, useState, useRef } from 'react';
|
import { useEffect, useState, useRef } from 'react';
|
||||||
import { databases, ID, Query } from "../../lib/appwrite"; // Added Query import
|
import { databases, ID, Query } from "../../lib/appwrite";
|
||||||
import { DATABASE_ID, COLLECTION_ID } from "../../lib/api";
|
import { DATABASE_ID, COLLECTION_ID } from "../../lib/api";
|
||||||
import Header from '../../components/partials/header';
|
import Header from '../../components/partials/header';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
export default function SingleBooked() {
|
function SingleBookedContent() {
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const nameParam = searchParams.get('name');
|
const nameParam = searchParams.get('name');
|
||||||
const dateParam = searchParams.get('date');
|
const dateParam = searchParams.get('date');
|
||||||
@ -20,7 +21,6 @@ export default function SingleBooked() {
|
|||||||
|
|
||||||
const generateTokenNumber = async (date) => {
|
const generateTokenNumber = async (date) => {
|
||||||
try {
|
try {
|
||||||
// Get the highest token number for the date
|
|
||||||
const response = await databases.listDocuments(
|
const response = await databases.listDocuments(
|
||||||
DATABASE_ID,
|
DATABASE_ID,
|
||||||
COLLECTION_ID,
|
COLLECTION_ID,
|
||||||
@ -35,45 +35,45 @@ export default function SingleBooked() {
|
|||||||
return (parseInt(lastToken) + 1).toString().padStart(3, '0');
|
return (parseInt(lastToken) + 1).toString().padStart(3, '0');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Token generation error:", error);
|
console.error("Token generation error:", error);
|
||||||
return "001"; // Fallback token number
|
return "001";
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const createBooking = async () => {
|
|
||||||
if (bookingCreated.current) return; // Prevent duplicate calls
|
|
||||||
|
|
||||||
try {
|
|
||||||
bookingCreated.current = true; // Mark as created
|
|
||||||
setLoading(true);
|
|
||||||
setError(null);
|
|
||||||
|
|
||||||
const generatedToken = await generateTokenNumber(appointmentDate);
|
|
||||||
|
|
||||||
await databases.createDocument(
|
|
||||||
DATABASE_ID,
|
|
||||||
COLLECTION_ID,
|
|
||||||
ID.unique(),
|
|
||||||
{
|
|
||||||
tokenNumber: generatedToken,
|
|
||||||
date: appointmentDate,
|
|
||||||
patientName: name,
|
|
||||||
status: "booked",
|
|
||||||
bookedBy: "staff",
|
|
||||||
patientId: ID.unique(),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
setToken(generatedToken);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Booking error:", error);
|
|
||||||
setError(error.message);
|
|
||||||
bookingCreated.current = false; // Reset on error to allow retry
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const createBooking = async () => {
|
||||||
|
if (bookingCreated.current) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
bookingCreated.current = true;
|
||||||
|
setLoading(true);
|
||||||
|
setError(null);
|
||||||
|
|
||||||
|
const generatedToken = await generateTokenNumber(appointmentDate);
|
||||||
|
|
||||||
|
await databases.createDocument(
|
||||||
|
DATABASE_ID,
|
||||||
|
COLLECTION_ID,
|
||||||
|
ID.unique(),
|
||||||
|
{
|
||||||
|
tokenNumber: generatedToken,
|
||||||
|
date: appointmentDate,
|
||||||
|
patientName: name,
|
||||||
|
status: "booked",
|
||||||
|
bookedBy: "staff",
|
||||||
|
patientId: ID.unique(),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
setToken(generatedToken);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Booking error:", error);
|
||||||
|
setError(error.message);
|
||||||
|
bookingCreated.current = false;
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (name && appointmentDate) {
|
if (name && appointmentDate) {
|
||||||
createBooking();
|
createBooking();
|
||||||
}
|
}
|
||||||
@ -125,4 +125,12 @@ export default function SingleBooked() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SingleBooked() {
|
||||||
|
return (
|
||||||
|
<Suspense fallback={<div>Loading...</div>}>
|
||||||
|
<SingleBookedContent />
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
}
|
}
|
@ -36,7 +36,7 @@ export default function SingleBooking() {
|
|||||||
// Get current date in YYYY-MM-DD format
|
// Get current date in YYYY-MM-DD format
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
const appointmentDate = today.toISOString().split('T')[0];
|
const appointmentDate = today.toISOString().split('T')[0];
|
||||||
|
|
||||||
// Navigate to confirmation page with name and current date as query params
|
// Navigate to confirmation page with name and current date as query params
|
||||||
router.push(`/pages/SingleBooked?name=${encodeURIComponent(name)}&date=${encodeURIComponent(appointmentDate)}`);
|
router.push(`/pages/SingleBooked?name=${encodeURIComponent(name)}&date=${encodeURIComponent(appointmentDate)}`);
|
||||||
};
|
};
|
||||||
@ -93,7 +93,7 @@ export default function SingleBooking() {
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div className="mt-6 text-center text-sm text-gray-600 dark:text-gray-300">
|
<div className="mt-6 text-center text-sm text-gray-600 dark:text-gray-300">
|
||||||
Note: Token booking is available for today's date only.
|
Note: Token booking is available for today's date only.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { databases,Query } from "../../lib/appwrite";
|
import { databases, Query } from "../../lib/appwrite";
|
||||||
import { DATABASE_ID, COLLECTION_ID } from "../../lib/api";
|
import { DATABASE_ID, COLLECTION_ID } from "../../lib/api";
|
||||||
import Header from "../../components/partials/header";
|
import Header from "../../components/partials/header";
|
||||||
import { useTheme } from "../../context/ThemeContext";
|
import { useTheme } from "../../context/ThemeContext";
|
||||||
@ -68,7 +68,7 @@ export default function StaffBooking() {
|
|||||||
{/* Statistics Overview */}
|
{/* Statistics Overview */}
|
||||||
<div className={`mb-8 p-6 rounded-lg ${darkMode ? 'bg-gray-800' : 'bg-gray-50'} border ${darkMode ? 'border-gray-700' : 'border-gray-200'}`}>
|
<div className={`mb-8 p-6 rounded-lg ${darkMode ? 'bg-gray-800' : 'bg-gray-50'} border ${darkMode ? 'border-gray-700' : 'border-gray-200'}`}>
|
||||||
<h3 className={`text-lg font-medium mb-4 ${darkMode ? 'text-white' : 'text-gray-800'}`}>
|
<h3 className={`text-lg font-medium mb-4 ${darkMode ? 'text-white' : 'text-gray-800'}`}>
|
||||||
Today's Overview
|
Today's Overview
|
||||||
</h3>
|
</h3>
|
||||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||||
<div className={`p-4 rounded-lg text-center ${darkMode ? 'bg-gray-700' : 'bg-white'} border ${darkMode ? 'border-gray-600' : 'border-gray-200'}`}>
|
<div className={`p-4 rounded-lg text-center ${darkMode ? 'bg-gray-700' : 'bg-white'} border ${darkMode ? 'border-gray-600' : 'border-gray-200'}`}>
|
||||||
@ -95,8 +95,8 @@ export default function StaffBooking() {
|
|||||||
<div
|
<div
|
||||||
onClick={() => router.push('/pages/SingleBooking')}
|
onClick={() => router.push('/pages/SingleBooking')}
|
||||||
className={`p-6 cursor-pointer rounded-lg border transition-all hover:shadow-md ${darkMode ?
|
className={`p-6 cursor-pointer rounded-lg border transition-all hover:shadow-md ${darkMode ?
|
||||||
'bg-gray-800 border-gray-700 hover:border-blue-600 hover:bg-gray-700' :
|
'bg-gray-800 border-gray-700 hover:border-blue-600 hover:bg-gray-700' :
|
||||||
'bg-white border-gray-200 hover:border-blue-500 hover:bg-blue-50'
|
'bg-white border-gray-200 hover:border-blue-500 hover:bg-blue-50'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
@ -117,8 +117,8 @@ export default function StaffBooking() {
|
|||||||
<div
|
<div
|
||||||
onClick={() => router.push('/pages/MultiBooking')}
|
onClick={() => router.push('/pages/MultiBooking')}
|
||||||
className={`p-6 cursor-pointer rounded-lg border transition-all hover:shadow-md ${darkMode ?
|
className={`p-6 cursor-pointer rounded-lg border transition-all hover:shadow-md ${darkMode ?
|
||||||
'bg-gray-800 border-gray-700 hover:border-blue-600 hover:bg-gray-700' :
|
'bg-gray-800 border-gray-700 hover:border-blue-600 hover:bg-gray-700' :
|
||||||
'bg-white border-gray-200 hover:border-blue-500 hover:bg-blue-50'
|
'bg-white border-gray-200 hover:border-blue-500 hover:bg-blue-50'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
|
@ -95,14 +95,14 @@ export default function EntriesTable() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (userRole === "patient") return; // Don't load data if patient
|
if (userRole === "patient") return; // Don't load data if patient
|
||||||
|
|
||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
try {
|
try {
|
||||||
const data = await getEntries();
|
const data = await getEntries();
|
||||||
setEntries(data);
|
setEntries(data);
|
||||||
setFilteredEntries(data);
|
setFilteredEntries(data);
|
||||||
updateTokenInfo(data);
|
updateTokenInfo(data);
|
||||||
|
|
||||||
// Load settings (avg consultation time)
|
// Load settings (avg consultation time)
|
||||||
// const settings = await getSettings();
|
// const settings = await getSettings();
|
||||||
// setAvgConsultTime(settings?.avgConsultationTime || 15);
|
// setAvgConsultTime(settings?.avgConsultationTime || 15);
|
||||||
@ -145,7 +145,7 @@ export default function EntriesTable() {
|
|||||||
<div className="flex items-center justify-center h-screen">
|
<div className="flex items-center justify-center h-screen">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<h1 className="text-2xl font-bold mb-4">Access Denied</h1>
|
<h1 className="text-2xl font-bold mb-4">Access Denied</h1>
|
||||||
<p>You don't have permission to view this page.</p>
|
<p>You don't have permission to view this page.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -162,8 +162,7 @@ export default function EntriesTable() {
|
|||||||
missedTokens={missedTokens}
|
missedTokens={missedTokens}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<h1 className="text-2xl font-bold mb-4">Today's Entries</h1>
|
<h1 className="text-2xl font-bold mb-4">Today's Entries</h1>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Search by token or name"
|
placeholder="Search by token or name"
|
||||||
@ -189,37 +188,35 @@ export default function EntriesTable() {
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{currentEntries.map((entry) => (
|
{currentEntries.map((entry) => (
|
||||||
<tr
|
<tr
|
||||||
key={entry.$id}
|
key={entry.$id}
|
||||||
className={`border ${darkMode ? 'border-gray-700' : 'border-gray-200'}`}
|
className={`border ${darkMode ? 'border-gray-700' : 'border-gray-200'}`}
|
||||||
>
|
>
|
||||||
<td className="p-3 font-mono">{entry.tokenNumber}</td>
|
<td className="p-3 font-mono">{entry.tokenNumber}</td>
|
||||||
<td className="p-3">{entry.patientName}</td>
|
<td className="p-3">{entry.patientName}</td>
|
||||||
<td className="p-3">
|
<td className="p-3">
|
||||||
<span className={`text-xs px-2 py-1 rounded ${
|
<span className={`text-xs px-2 py-1 rounded ${entry.bookedBy === 'staff' ?
|
||||||
entry.bookedBy === 'staff' ?
|
'bg-purple-100 text-purple-800' :
|
||||||
'bg-purple-100 text-purple-800' :
|
|
||||||
'bg-blue-100 text-blue-800'
|
'bg-blue-100 text-blue-800'
|
||||||
}`}>
|
}`}>
|
||||||
{entry.bookedBy}
|
{entry.bookedBy}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="p-3">
|
<td className="p-3">
|
||||||
<span
|
<span
|
||||||
className={`px-2 py-1 rounded-full text-xs ${
|
className={`px-2 py-1 rounded-full text-xs ${entry.status === "done"
|
||||||
entry.status === "done"
|
|
||||||
? "bg-green-100 text-green-800"
|
? "bg-green-100 text-green-800"
|
||||||
: entry.status === "booked"
|
: entry.status === "booked"
|
||||||
? "bg-yellow-100 text-yellow-800"
|
? "bg-yellow-100 text-yellow-800"
|
||||||
: "bg-red-100 text-red-800"
|
: "bg-red-100 text-red-800"
|
||||||
} font-semibold`}
|
} font-semibold`}
|
||||||
>
|
>
|
||||||
{entry.status}
|
{entry.status}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="p-3">
|
<td className="p-3">
|
||||||
{entry.status === "booked" ?
|
{entry.status === "booked" ?
|
||||||
`~${calculateWaitTime(entry.tokenNumber)} mins` :
|
`~${calculateWaitTime(entry.tokenNumber)} mins` :
|
||||||
'-'}
|
'-'}
|
||||||
</td>
|
</td>
|
||||||
<td className="p-3 flex gap-2">
|
<td className="p-3 flex gap-2">
|
||||||
@ -246,9 +243,8 @@ export default function EntriesTable() {
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
{/* Pagination */}
|
{/* Pagination */}
|
||||||
<div className={`flex justify-between items-center mt-4 ${
|
<div className={`flex justify-between items-center mt-4 ${darkMode ? 'text-white' : 'text-gray-700'
|
||||||
darkMode ? 'text-white' : 'text-gray-700'
|
}`}>
|
||||||
}`}>
|
|
||||||
<button
|
<button
|
||||||
disabled={currentPage === 1}
|
disabled={currentPage === 1}
|
||||||
onClick={() => setCurrentPage((prev) => prev - 1)}
|
onClick={() => setCurrentPage((prev) => prev - 1)}
|
||||||
|
Loading…
Reference in New Issue
Block a user