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 Rawnaf AI Assistant - Solve Any Work with AI Power
FILE: client/src/index.css @tailwind base; @tailwind components; @tailwind utilities; body { @apply bg-dark text-gray-100; } .btn-primary { @apply bg-primary hover:bg-purple-700 text-white font-bold py-2 px-6 rounded-lg transition duration-300; } .btn-secondary { @apply bg-gray-700 hover:bg-gray-600 text-white font-bold py-2 px-6 rounded-lg transition duration-300; } .card { @apply bg-card p-6 rounded-xl border border-gray-800 hover:border-primary transition duration-300; } .input { @apply w-full bg-gray-900 border border-gray-700 rounded-lg px-4 py-2 focus:border-primary outline-none; } FILE: client/src/index.js import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import { AuthProvider } from './context/AuthContext'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(); FILE: client/src/utils/api.js import axios from 'axios'; const api = axios.create({ baseURL: process.env.REACT_APP_API_URL }); api.interceptors.request.use(config => { const token = localStorage.getItem('token'); if (token) config.headers['x-auth-token'] = token; return config; }); export default api; FILE: client/src/context/AuthContext.jsx import { createContext, useState, useEffect } from 'react'; import api from '../utils/api'; export const AuthContext = createContext(); export const AuthProvider = ({ children }) => { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const loadUser = async () => { const token = localStorage.getItem('token'); if (token) { try { const res = await api.get('/auth/me'); setUser(res.data); } catch { localStorage.removeItem('token'); } } setLoading(false); }; loadUser(); }, []); const login = async (email, password) => { const res = await api.post('/auth/login', { email, password }); localStorage.setItem('token', res.data.token); setUser(res.data.user); return res.data; }; const register = async (name, email, password) => { const res = await api.post('/auth/register', { name, email, password }); localStorage.setItem('token', res.data.token); setUser(res.data.user); return res.data; }; const logout = () => { localStorage.removeItem('token'); setUser(null); }; return {children}; }; FILE: client/src/components/ProtectedRoute.jsx import { useContext } from 'react'; import { Navigate } from 'react-router-dom'; import { AuthContext } from '../context/AuthContext'; export default function ProtectedRoute({ children }) { const { user, loading } = useContext(AuthContext); if (loading) return
Loading...
; return user? children : ; } FILE: client/src/components/AdminRoute.jsx import { useContext } from 'react'; import { Navigate } from 'react-router-dom'; import { AuthContext } from '../context/AuthContext'; export default function AdminRoute({ children }) { const { user, loading } = useContext(AuthContext); if (loading) return
Loading...
; return user?.role === 'admin'? children : ; } FILE: client/src/components/Navbar.jsx import { Link } from 'react-router-dom'; import { useContext } from 'react'; import { AuthContext } from '../context/AuthContext'; export default function Navbar() { const { user, logout } = useContext(AuthContext); return ( ); } FILE: client/src/components/Footer.jsx import { Link } from 'react-router-dom'; export default function Footer() { return (

Rawnaf AI Assistant

Solve Any Work with AI Power

FB IG TW

Company

About Us Terms Privacy Policy

Services

AI Marketing

Social Automation

Ads Management

Data Entry AI

Payment Info

Email: k_rahman10@yahoo.com

bKash: 01969431900

© 2024 Rawnaf AI Assistant. All rights reserved.
); } FILE: client/src/components/AdBanner.jsx import { useEffect, useState } from 'react'; import api from '../utils/api'; export default function AdBanner() { const [ads, setAds] = useState([]); useEffect(() => { api.get('/ads').then(res => setAds(res.data)).catch(() => {}); }, []); if (!ads.length) return null; return (
{ads.map(ad => ( {ad.title} ))}
); } FILE: client/src/components/ServiceCard.jsx import { Link } from 'react-router-dom'; export default function ServiceCard({ service }) { return (

{service.title}

{service.description}

    {service.features.map((f, i) => (
  • ✓ {f}
  • ))}
à§³{service.price} Buy Now
); } FILE: client/src/App.jsx import { BrowserRouter, Routes, Route } from 'react-router-dom'; import Navbar from './components/Navbar'; import Footer from './components/Footer'; import Home from './pages/Home'; import Services from './pages/Services'; import Pricing from './pages/Pricing'; import Login from './pages/Login'; import Register from './pages/Register'; import Dashboard from './pages/Dashboard'; import Payment from './pages/Payment'; import AdminPanel from './pages/AdminPanel'; import About from './pages/About'; import Terms from './pages/Terms'; import Privacy from './pages/Privacy'; import ProtectedRoute from './components/ProtectedRoute'; import AdminRoute from './components/AdminRoute'; function App() { return (
} /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } />
); } export default App; FILE: client/src/pages/Home.jsx import { Link } from 'react-router-dom'; import AdBanner from '../components/AdBanner'; export default function Home() { return (

Solve Any Work with AI Power

Rawnaf AI Assistant handles your secretary work, sales, marketing, Facebook posting, Instagram automation, and daily productivity tasks automatically.

Get Started View Pricing

AI Services We Offer

{['AI Marketing', 'Social Automation', 'Data Entry AI', 'Ads Management'].map(s => (
🤖

{s}

Powered by advanced AI to save you time

))}
); } FILE: client/src/pages/Services.jsx import { useEffect, useState } from 'react'; import api from '../utils/api'; import ServiceCard from '../components/ServiceCard'; export default function Services() { const [services, setServices] = useState([]); useEffect(() => { api.get('/services').then(res => setServices(res.data)); }, []); return (

Our AI Services

Choose the perfect AI solution for your business

{services.map(s => )}
); } FILE: client/src/pages/Pricing.jsx import { useEffect, useState } from 'react'; import api from '../utils/api'; import ServiceCard from '../components/ServiceCard'; export default function Pricing() { const [services, setServices] = useState([]); useEffect(() => { api.get('/services').then(res => setServices(res.data)); }, []); return (

Simple Pricing

One-time payment. Manual bKash process. No hidden fees.

{services.map(s => )}

Payment Methods

Email: k_rahman10@yahoo.com

bKash: 01969431900

Send payment, upload screenshot, admin will approve within 24 hours

); } FILE: client/src/pages/Login.jsx import { useState, useContext } from 'react'; import { useNavigate, Link } from 'react-router-dom'; import { AuthContext } from '../context/AuthContext'; export default function Login() { const [form, setForm] = useState({ email: '', password: '' }); const [error, setError] = useState(''); const { login } = useContext(AuthContext); const nav = useNavigate(); const handleSubmit = async (e) => { e.preventDefault(); try { await login(form.email, form.password); nav('/dashboard'); } catch (err) { setError(err.response?.data?.msg || 'Login failed'); } }; return (