/** * Valley Trader Classified Ad System (Mobile Optimized) * Single-Page Deployable Version */ const express = require('express'); const multer = require('multer'); const fs = require('fs'); const path = require('path'); const nodemailer = require('nodemailer'); const app = express(); const PORT = process.env.PORT || 3000; // Middleware app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use('/uploads', express.static(path.join(__dirname, 'uploads'))); const uploadDir = path.join(__dirname, 'uploads'); if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir); // Multer for image uploads const storage = multer.diskStorage({ destination: (_, __, cb) => cb(null, 'uploads/'), filename: (_, file, cb) => cb(null, Date.now() + '-' + file.originalname) }); const upload = multer({ storage }); // Email setup (Gmail example) const transporter = nodemailer.createTransport({ service: 'gmail', auth: { user: process.env.EMAIL_USER || 'YOUR_GMAIL@gmail.com', pass: process.env.EMAIL_PASS || 'YOUR_APP_PASSWORD' } }); // Ads data helpers const adsFile = path.join(__dirname, 'ads.json'); function loadAds() { return fs.existsSync(adsFile) ? JSON.parse(fs.readFileSync(adsFile)) : []; } function saveAds(ads) { fs.writeFileSync(adsFile, JSON.stringify(ads, null, 2)); } // Serve single HTML interface app.get('/', (_, res) => res.send(` The Valley Trader Classifieds

The Valley Trader Classifieds

๐Ÿ“ข Submit Your Ad

Word count: 0

๐Ÿงพ Admin Dashboard

DateTitleDescription IssuesPricePhotoStatus
`)); // --- API Endpoints --- app.post('/submit-ad', upload.single('photo'), async (req, res) => { try { const { title, description, issues, totalPrice } = req.body; const photo = req.file ? req.file.filename : ''; const ads = loadAds(); const ad = { title, description, issues, totalPrice, photo, paid:false, date:new Date() }; ads.push(ad); saveAds(ads); await transporter.sendMail({ from: process.env.EMAIL_USER, to: 'thevalleytrader@yahoo.com', subject: 'New Classified Ad Submitted', html: \`

New Ad

Title: \${title}

Description: \${description}

Issues: \${issues}

Total: $\${totalPrice}

\` }); res.json({ success:true }); } catch (e) { console.error(e); res.json({ success:false }); } }); app.get('/admin/ads', (_, res) => res.json(loadAds())); app.post('/admin/mark-paid', (req, res) => { const { index } = req.body; const ads=loadAds(); if(ads[index]){ads[index].paid=true;saveAds(ads);} res.json({ success:true }); }); app.listen(PORT,()=>console.log('โœ… Valley Trader app running on http://localhost:'+PORT));