PROJECT: RAWNAF AI ASSISTANT - FULL STACK SAAS TAGLINE: "Solve Any Work with AI Power" TECH: React.js + Tailwind | Node.js + Express | MongoDB | JWT INSTALLATION STEPS: 1. Create folder: rawnaf-ai-assistant 2. Create all files below with exact paths 3. cd server && npm install 4. cd client && npm install 5. Create server/.env from.env.example below 6. Create client/.env with REACT_APP_API_URL=http://localhost:5000/api 7. Run: cd server && npm run dev 8. Run: cd client && npm start 9. Login admin: admin@rawnaf.com / admin123 DEPLOY: Vercel for /client, Render/Railway for /server FILE:.env.example PORT=5000 MONGO_URI=mongodb+srv://user:pass@cluster.mongodb.net/rawnaf JWT_SECRET=rawnaf_secret_key_change_in_production_2024 CLIENT_URL=http://localhost:3000 ADMIN_EMAIL=admin@rawnaf.com ADMIN_PASSWORD=admin123 OPENAI_API_KEY=sk-xxx_optional_for_ai_features FILE:.gitignore node_modules .env client/.env client/build server/uploads/* !server/uploads/.gitkeep .DS_Store FILE: server/package.json { "name": "rawnaf-server", "version": "1.0.0", "main": "server.js", "scripts": { "start": "node server.js", "dev": "nodemon server.js" }, "dependencies": { "bcryptjs": "^2.4.3", "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.19.2", "express-rate-limit": "^7.4.0", "express-validator": "^7.1.0", "jsonwebtoken": "^9.0.2", "mongoose": "^8.5.1", "multer": "^1.4.5-lts.1", "openai": "^4.52.7" }, "devDependencies": { "nodemon": "^3.1.4" } } FILE: server/server.js require('dotenv').config(); const express = require('express'); const cors = require('cors'); const rateLimit = require('express-rate-limit'); const path = require('path'); const connectDB = require('./config/db'); const app = express(); connectDB(); app.use(cors({ origin: process.env.CLIENT_URL, credentials: true })); app.use(express.json()); app.use('/uploads', express.static(path.join(__dirname, 'uploads'))); const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }); app.use('/api/', limiter); app.use('/api/auth', require('./routes/auth')); app.use('/api/services', require('./routes/services')); app.use('/api/payments', require('./routes/payments')); app.use('/api/ads', require('./routes/ads')); app.use('/api/admin', require('./routes/admin')); app.use('/api/ai', require('./routes/ai')); app.get('/', (req, res) => res.json({ msg: 'Rawnaf AI Assistant API Running' })); const Service = require('./models/Service'); setTimeout(async () => { const count = await Service.countDocuments(); if (count === 0) { await Service.insertMany([ { title: 'AI Marketing', description: 'Auto generate ad campaigns and copy for Facebook, Instagram, Google', price: 2999, features: ['Facebook Ads', 'Instagram Ads', 'Email Campaigns', 'Copy Generator'] }, { title: 'Social Media Automation', description: 'Auto post to Facebook and Instagram with AI captions', price: 1999, features: ['Schedule Posts', 'Caption Generator', 'Hashtag Research', 'Auto Reply'] }, { title: 'Data Entry AI', description: 'AI powered data processing and automation', price: 999, features: ['OCR', 'Excel Automation', 'Web Scraping', 'PDF to Excel'] }, { title: 'Ads Management', description: 'Complete management of your ad accounts', price: 4999, features: ['Strategy', 'Optimization', 'Weekly Reporting', 'A/B Testing'] } ]); } }, 2000); const PORT = process.env.PORT || 5000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`)); FILE: server/config/db.js const mongoose = require('mongoose'); const bcrypt = require('bcryptjs'); const User = require('../models/User'); const connectDB = async () => { try { await mongoose.connect(process.env.MONGO_URI); console.log('MongoDB Connected'); const adminExists = await User.findOne({ email: process.env.ADMIN_EMAIL }); if (!adminExists) { const hashed = await bcrypt.hash(process.env.ADMIN_PASSWORD, 10); await User.create({ name: 'Admin', email: process.env.ADMIN_EMAIL, password: hashed, role: 'admin' }); console.log('Default admin created'); } } catch (err) { console.error(err.message); process.exit(1); } }; module.exports = connectDB; FILE: server/middleware/auth.js const jwt = require('jsonwebtoken'); const User = require('../models/User'); module.exports = async (req, res, next) => { const token = req.header('x-auth-token'); if (!token) return res.status(401).json({ msg: 'No token, access denied' }); try { const decoded = jwt.verify(token, process.env.JWT_SECRET); req.user = await User.findById(decoded.id).select('-password'); if (!req.user) return res.status(401).json({ msg: 'User not found' }); next(); } catch (err) { res.status(401).json({ msg: 'Token invalid' }); } }; FILE: server/middleware/admin.js module.exports = (req, res, next) => { if (req.user && req.user.role === 'admin') { next(); } else { res.status(403).json({ msg: 'Admin access required' }); } }; FILE: server/models/User.js const mongoose = require('mongoose'); const UserSchema = new mongoose.Schema({ name: { type: String, required: true }, email: { type: String, required: true, unique: true }, password: { type: String, required: true }, role: { type: String, enum: ['user', 'admin'], default: 'user' }, purchasedServices: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Service' }], createdAt: { type: Date, default: Date.now } }); module.exports = mongoose.model('User', UserSchema); FILE: server/models/Service.js const mongoose = require('mongoose'); const ServiceSchema = new mongoose.Schema({ title: { type: String, required: true }, description: { type: String, required: true }, price: { type: Number, required: true }, features: [String], active: { type: Boolean, default: true } }); module.exports = mongoose.model('Service', ServiceSchema); FILE: server/models/Payment.js const mongoose = require('mongoose'); const PaymentSchema = new mongoose.Schema({ user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, service: { type: mongoose.Schema.Types.ObjectId, ref: 'Service', required: true }, transactionId: { type: String, required: true }, screenshot: { type: String, required: true }, status: { type: String, enum: ['pending', 'approved', 'rejected'], default: 'pending' }, createdAt: { type: Date, default: Date.now } }); module.exports = mongoose.model('Payment', PaymentSchema); FILE: server/models/Ad.js const mongoose = require('mongoose'); const AdSchema = new mongoose.Schema({ title: { type: String, required: true }, imageUrl: { type: String, required: true }, link: String, active: { type: Boolean, default: true }, createdAt: { type: Date, default: Date.now } }); module.exports = mongoose.model('Ad', AdSchema); FILE: server/models/Notification.js const mongoose = require('mongoose'); const NotificationSchema = new mongoose.Schema({ user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, message: { type: String, required: true }, read: { type: Boolean, default: false }, createdAt: { type: Date, default: Date.now } }); module.exports = mongoose.model('Notification', NotificationSchema); FILE: server/routes/auth.js const express = require('express'); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const { body, validationResult } = require('express-validator'); const User = require('../models/User'); const auth = require('../middleware/auth'); const router = express.Router(); router.post('/register', [ body('name').notEmpty(), body('email').isEmail(), body('password').isLength({ min: 6 }) ], async (req, res) => { const errors = validationResult(req); if (!errors.isEmpty()) return res.status(400).json({ errors: errors.array() }); const { name, email, password } = req.body; try { let user = await User.findOne({ email }); if (user) return res.status(400).json({ msg: 'User already exists' }); const hashed = await bcrypt.hash(password, 10); user = await User.create({ name, email, password: hashed }); const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: '7d' }); res.json({ token, user: { id: user._id, name, email, role: user.role } }); } catch (err) { res.status(500).send('Server error'); } }); router.post('/login', async (req, res) => { const { email, password } = req.body; try { const user = await User.findOne({ email }); if (!user) return res.status(400).json({ msg: 'Invalid credentials' }); const isMatch = await bcrypt.compare(password, user.password); if (!isMatch) return res.status(400).json({ msg: 'Invalid credentials' }); const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: '7d' }); res.json({ token, user: { id: user._id, name: user.name, email, role: user.role } }); } catch (err) { res.status(500).send('Server error'); } }); router.get('/me', auth, (req, res) => res.json(req.user)); module.exports = router; FILE: server/routes/services.js const express = require('express'); const Service = require('../models/Service'); const auth = require('../middleware/auth'); const admin = require('../middleware/admin'); const router = express.Router(); router.get('/', async (req, res) => { const services = await Service.find({ active: true }); res.json(services); }); router.post('/', [auth, admin], async (req, res) => { const service = await Service.create(req.body); res.json(service); }); router.put('/:id', [auth, admin], async (req, res) => { const service = await Service.findByIdAndUpdate(req.params.id, req.body, { new: true }); res.json(service); }); router.delete('/:id', [auth, admin], async (req, res) => { await Service.findByIdAndDelete(req.params.id); res.json({ msg: 'Deleted' }); }); module.exports = router; FILE: server/routes/payments.js const express = require('express'); const multer = require('multer'); const path = require('path'); const Payment = require('../models/Payment'); const auth = require('../middleware/auth'); const router = express.Router(); const storage = multer.diskStorage({ destination: './uploads/', filename: (req, file, cb) => cb(null, Date.now() + path.extname(file.originalname)) }); const upload = multer({ storage }); router.post('/', [auth, upload.single('screenshot')], async (req, res) => { const { serviceId, transactionId } = req.body; const payment = await Payment.create({ user: req.user.id, service: serviceId, transactionId, screenshot: req.file.filename }); res.json(payment); }); router.get('/my', auth, async (req, res) => { const payments = await Payment.find({ user: req.user.id }).populate('service'); res.json(payments); }); module.exports = router; FILE: server/routes/admin.js const express = require('express'); const User = require('../models/User'); const Payment = require('../models/Payment'); const Notification = require('../models/Notification'); const auth = require('../middleware/auth'); const admin = require('../middleware/admin'); const router = express.Router(); router.get('/stats', [auth, admin], async (req, res) => { const totalUsers = await User.countDocuments({ role: 'user' }); const totalSales = await Payment.countDocuments({ status: 'approved' }); const pendingPayments = await Payment.countDocuments({ status: 'pending' }); res.json({ totalUsers, totalSales, pendingPayments }); }); router.get('/payments', [auth, admin], async (req, res) => { const payments = await Payment.find().populate('user', 'name email').populate('service'); res.json(payments); }); router.put('/payments/:id/approve', [auth, admin], async (req, res) => { const payment = await Payment.findById(req.params.id); payment.status = 'approved'; await payment.save(); await User.findByIdAndUpdate(payment.user, { $addToSet: { purchasedServices: payment.service } }); await Notification.create({ user: payment.user, message: 'Your payment was approved. Service unlocked!' }); res.json(payment); }); router.put('/payments/:id/reject', [auth, admin], async (req, res) => { const payment = await Payment.findByIdAndUpdate(req.params.id, { status: 'rejected' }, { new: true }); await Notification.create({ user: payment.user, message: 'Your payment was rejected. Please contact support.' }); res.json(payment); }); router.get('/users', [auth, admin], async (req, res) => { const users = await User.find().select('-password').populate('purchasedServices'); res.json(users); }); module.exports = router; FILE: server/routes/ads.js const express = require('express'); const Ad = require('../models/Ad'); const auth = require('../middleware/auth'); const admin = require('../middleware/admin'); const router = express.Router(); router.get('/', async (req, res) => { const ads = await Ad.find({ active: true }); res.json(ads); }); router.post('/', [auth, admin], async (req, res) => { const ad = await Ad.create(req.body); res.json(ad); }); router.put('/:id', [auth, admin], async (req, res) => { const ad = await Ad.findByIdAndUpdate(req.params.id, req.body, { new: true }); res.json(ad); }); router.delete('/:id', [auth, admin], async (req, res) => { await Ad.findByIdAndDelete(req.params.id); res.json({ msg: 'Deleted' }); }); module.exports = router; FILE: server/routes/ai.js const express = require('express'); const { OpenAI } = require('openai'); const auth = require('../middleware/auth'); const User = require('../models/User'); const router = express.Router(); const openai = process.env.OPENAI_API_KEY? new OpenAI({ apiKey: process.env.OPENAI_API_KEY }) : null; router.post('/generate', auth, async (req, res) => { const { prompt, type } = req.body; const hasAccess = req.user.purchasedServices.length > 0 || req.user.role === 'admin'; if (!hasAccess) return res.status(403).json({ msg: 'Purchase a service to use AI features' }); if (!openai) { const demo = { 'facebook_post': '🚀 Boost your business with AI! Rawnaf AI Assistant handles your social media, sales, and marketing 24/7. Try it now! #AIAssistant #Marketing #Productivity', 'instagram_caption': 'Solving work with AI power ✨\n1. Automate your social media\n2. Generate content in seconds\n3. Focus on what matters\n#RawnafAI #AIMarketing #ContentCreator', 'marketing_copy': 'Tired of manual work? Rawnaf AI Assistant is your 24/7 secretary, marketer, and content creator. Generate posts, manage sales, automate tasks. Start solving any work with AI power today.' }; return res.json({ result: demo[type] || 'Demo mode: Connect OpenAI API key for real AI generation.' }); } try { const completion = await openai.chat.completions.create({ model: "gpt-4o-mini", messages: [{ role: "user", content: `You are Rawnaf AI Assistant. Generate ${type}: ${prompt}` }], max_tokens: 300 }); res.json({ result: completion.choices[0].message.content }); } catch (err) { res.status(500).json({ msg: 'AI generation failed' }); } }); module.exports = router; FILE: client/package.json { "name": "rawnaf-client", "version": "1.0.0", "dependencies": { "axios": "^1.7.2", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.25.1", "react-scripts": "5.0.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build" }, "devDependencies": { "autoprefixer": "^10.4.19", "postcss": "^8.4.39", "tailwindcss": "^3.4.6" } } FILE: client/tailwind.config.js module.exports = { content: ["./src/**/*.{js,jsx}"], theme: { extend: { colors: { primary: '#8B5CF6', dark: '#0F0F1E', card: '#1A1A2E' } }, }, plugins: [], } FILE: client/postcss.config.js module.exports = { plugins: { tailwindcss: {}, autoprefixer: {}, }, } FILE: client/public/index.html