skip to Main Content

So im trying to create a small cafe website using react. customer told me that he wanted his orders to be be visible on admin dashboard, so i thought i would make something like this:

import React from 'react';
import { OrderType } from './types';
import { Check } from 'lucide-react';
import fs from 'fs';
import path from 'path';

const ORDERS_FILE = "orders.json";

export function saveOrder(order2: OrderType): void {
  let orders: OrderType[] = [];
  
  const data = fs.readFileSync(ORDERS_FILE, 'utf8');
  orders = JSON.parse(data);
  orders.push(order2);

  fs.writeFileSync(ORDERS_FILE, JSON.stringify(orders, null, 2));
}

type OrderConfirmationProps = {
  order: OrderType;
  onClose: () => void;
};

export function OrderConfirmation({ order, onClose }: OrderConfirmationProps) {
  saveOrder(order);
  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center p-4">
      <div className="bg-white rounded-lg p-6 max-w-md w-full">
        <div className="flex items-center justify-center mb-6">
          <div className="bg-green-100 rounded-full p-2">
            <Check className="w-8 h-8 text-green-600" />
          </div>
        </div>
        <h3 className="text-xl font-semibold text-center mb-4">Order Confirmed!</h3>
        <p className="text-center mb-4">Your order ID is: <br />
          <span className="font-mono bg-gray-100 px-2 py-1 rounded">{order.id}</span>
        </p>
        <div className="border-t border-b py-4 my-4">
          <h4 className="font-semibold mb-2">Order Summary:</h4>
          {order.items.map((item) => (
            <div key={item.id} className="flex justify-between text-sm">
              <span>{item.quantity}x {item.name}</span>
              <span>${(parseFloat(item.price) * item.quantity).toFixed(2)}</span>
            </div>
          ))}
        </div>
        <div className="flex justify-between font-semibold mb-6">
          <span>Total:</span>
          <span>${order.totalPrice.toFixed(2)}</span>
        </div>
        <button
          onClick={onClose}
          className="w-full bg-amber-700 text-white px-4 py-2 rounded hover:bg-amber-800 transition-colors"
        >
          Close
        </button>
      </div>
    </div>
  );
}

it was all working untill i added saveOrder() function.

it shows me this error on console:

Uncaught Error: Module "fs" has been externalized for browser compatibility. Cannot access "fs.readFileSync" in client code.  See https://vitejs.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.

I was trying to fix this, but to be honest, i have no idea how paths work.

2

Answers


  1. Chosen as BEST ANSWER

    first of all thanks for everyone who tried to provide me with the solution.

    but i realized that i was trying to save order data at client side. as a solution, i just found a json server hosting website. (btw if you need, i would definetly recommend npoint.io)


  2. The fs (file system) module is a Node.js module and is not available in the browser environment. You need to store in a local storage or any back end service

    import React from 'react';
    import { OrderType } from './types';
    import { Check } from 'lucide-react';
    
    const ORDERS_KEY = "orders";
    
    export function saveOrder(order2: OrderType): void {
      // Get the existing orders from localStorage (if any)
      const storedOrders = localStorage.getItem(ORDERS_KEY);
      let orders: OrderType[] = storedOrders ? JSON.parse(storedOrders) : [];
    
      // Add the new order to the array
      orders.push(order2);
    
      // Save the updated orders array back to localStorage
      localStorage.setItem(ORDERS_KEY, JSON.stringify(orders));
    }
    
    type OrderConfirmationProps = {
      order: OrderType;
      onClose: () => void;
    };
    
    export function OrderConfirmation({ order, onClose }: OrderConfirmationProps) {
      // Save the order to localStorage
      saveOrder(order);
    
      return (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center p-4">
          <div className="bg-white rounded-lg p-6 max-w-md w-full">
            <div className="flex items-center justify-center mb-6">
              <div className="bg-green-100 rounded-full p-2">
                <Check className="w-8 h-8 text-green-600" />
              </div>
            </div>
            <h3 className="text-xl font-semibold text-center mb-4">Order Confirmed!</h3>
            <p className="text-center mb-4">Your order ID is: <br />
              <span className="font-mono bg-gray-100 px-2 py-1 rounded">{order.id}</span>
            </p>
            <div className="border-t border-b py-4 my-4">
              <h4 className="font-semibold mb-2">Order Summary:</h4>
              {order.items.map((item) => (
                <div key={item.id} className="flex justify-between text-sm">
                  <span>{item.quantity}x {item.name}</span>
                  <span>${(parseFloat(item.price) * item.quantity).toFixed(2)}</span>
                </div>
              ))}
            </div>
            <div className="flex justify-between font-semibold mb-6">
              <span>Total:</span>
              <span>${order.totalPrice.toFixed(2)}</span>
            </div>
            <button
              onClick={onClose}
              className="w-full bg-amber-700 text-white px-4 py-2 rounded hover:bg-amber-800 transition-colors"
            >
              Close
            </button>
          </div>
        </div>
      );
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search