horapi / index.js
ShieldX's picture
Upload 3 files
c701a3c verified
const express = require('express');
const cors = require('cors');
const { initializeApp, cert } = require('firebase-admin/app');
const { getFirestore } = require('firebase-admin/firestore');
require('dotenv').config();
const app = express();
// Middleware
app.use(cors());
app.use(express.json());
// --- FIREBASE ADMIN SETUP ---
// We check if we are in Production (HuggingFace) or Local
let serviceAccount;
if (process.env.FIREBASE_SERVICE_ACCOUNT) {
// In Production: We will store the JSON inside an ENV variable
serviceAccount = JSON.parse(process.env.FIREBASE_SERVICE_ACCOUNT);
} else {
// In Local: We read the file
try {
serviceAccount = require('./serviceAccountKey.json');
} catch (e) {
console.error("❌ Error: serviceAccountKey.json not found in server folder.");
}
}
if (serviceAccount) {
initializeApp({
credential: cert(serviceAccount)
});
console.log("βœ… Firebase Admin Connected");
}
const db = getFirestore();
// --- ROUTES ---
// 1. Health Check (To verify server is running)
app.get('/', (req, res) => {
res.send('House of Ruqa API is Running πŸ’Ž');
});
// 2. Get All Outfits
app.get('/api/outfits', async (req, res) => {
try {
const snapshot = await db.collection('outfits').get();
if (snapshot.empty) {
return res.json([]);
}
const outfits = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
res.json(outfits);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// 3. Get Single Outfit by ID
app.get('/api/outfits/:id', async (req, res) => {
try {
const docRef = db.collection('outfits').doc(req.params.id);
const docSnap = await docRef.get();
if (!docSnap.exists) {
return res.status(404).json({ error: 'Outfit not found' });
}
res.json({ id: docSnap.id, ...docSnap.data() });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// 4. Create Booking Request (Status: Pending)
app.post('/api/request-booking', async (req, res) => {
try {
const { outfitId, userId, pickupDate, returnDate, totalAmount, outfitTitle } = req.body;
// Add to 'bookings' collection
const bookingRef = await db.collection('bookings').add({
outfitId,
outfitTitle,
userId,
pickupDate,
returnDate,
totalAmount,
status: 'pending', // Default status
paymentVerified: false,
timestamp: new Date().toISOString()
});
res.status(200).json({ success: true, bookingId: bookingRef.id });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// 5. Admin Confirm Booking
app.post('/api/confirm-booking/:id', async (req, res) => {
try {
const bookingId = req.params.id;
await db.collection('bookings').doc(bookingId).update({
status: 'confirmed',
paymentVerified: true
});
res.json({ success: true, message: "Booking confirmed" });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// --- SERVER START ---
const PORT = process.env.PORT || 7860; // 7860 is required for HuggingFace Spaces
app.listen(PORT, () => {
console.log(`πŸš€ Server running on port ${PORT}`);
});