/** * Demo server for SmartSolTech website * Uses mock data instead of MongoDB for demonstration */ const express = require('express'); const path = require('path'); const cookieParser = require('cookie-parser'); const session = require('express-session'); const flash = require('connect-flash'); const helmet = require('helmet'); const compression = require('compression'); const rateLimit = require('express-rate-limit'); const app = express(); const PORT = process.env.PORT || 3000; // Security middleware app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net", "https://cdnjs.cloudflare.com", "https://unpkg.com"], scriptSrc: ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net", "https://cdnjs.cloudflare.com", "https://unpkg.com"], imgSrc: ["'self'", "data:", "https:", "blob:"], fontSrc: ["'self'", "https://cdnjs.cloudflare.com"], connectSrc: ["'self'", "https:"], mediaSrc: ["'self'"], frameSrc: ["'none'"] } } })); // Rate limiting const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // limit each IP to 100 requests per windowMs message: 'Too many requests from this IP, please try again later.' }); app.use(limiter); // Compression app.use(compression()); // View engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); // Middleware app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true, limit: '10mb' })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); // Session configuration app.use(session({ secret: 'demo-secret-key', resave: false, saveUninitialized: false, cookie: { secure: false, // Set to true in production with HTTPS maxAge: 24 * 60 * 60 * 1000 // 24 hours } })); // Flash messages app.use(flash()); // Global variables for templates app.use((req, res, next) => { res.locals.success_msg = req.flash('success'); res.locals.error_msg = req.flash('error'); res.locals.error = req.flash('error'); res.locals.currentYear = new Date().getFullYear(); next(); }); // Mock data const mockPortfolio = [ { _id: '1', title: 'E-commerce 플랫폼', description: '현대적인 온라인 쇼핑몰 플랫폼을 개발했습니다. React와 Node.js를 활용하여 높은 성능과 사용자 경험을 제공하며, 결제 시스템과 재고 관리 기능을 포함합니다.', shortDescription: '반응형 온라인 쇼핑몰 플랫폼 개발', category: 'web-development', technologies: ['React', 'Node.js', 'MongoDB', 'Express', 'Stripe', 'AWS'], images: [ { url: '/images/portfolio/ecommerce-1.jpg', alt: 'E-commerce 메인페이지', isPrimary: true } ], clientName: '패션 브랜드 ABC', projectUrl: 'https://example-ecommerce.demo', status: 'completed', featured: true, publishedAt: new Date('2024-01-15'), completedAt: new Date('2024-01-10'), isPublished: true, viewCount: 150, likes: 25 }, { _id: '2', title: '모바일 피트니스 앱', description: 'React Native를 사용하여 크로스플랫폼 피트니스 애플리케이션을 개발했습니다. 운동 계획, 칼로리 추적, 소셜 기능을 포함하여 사용자들의 건강한 라이프스타일을 지원합니다.', shortDescription: '건강 관리를 위한 크로스플랫폼 모바일 앱', category: 'mobile-app', technologies: ['React Native', 'Redux', 'Firebase', 'Node.js', 'PostgreSQL'], images: [ { url: '/images/portfolio/fitness-1.jpg', alt: '피트니스 앱 메인화면', isPrimary: true } ], clientName: '헬스케어 스타트업 FIT', status: 'completed', featured: true, publishedAt: new Date('2024-02-20'), completedAt: new Date('2024-02-15'), isPublished: true, viewCount: 200, likes: 35 }, { _id: '3', title: '기업 웹사이트 리뉴얼', description: '기업의 브랜드 아이덴티티를 반영한 웹사이트 리뉴얼 프로젝트입니다. 사용자 경험을 개선하고 모던한 디자인을 적용하여 브랜드 가치를 높였습니다.', shortDescription: '브랜드 아이덴티티를 반영한 기업 웹사이트 리뉴얼', category: 'ui-ux-design', technologies: ['Figma', 'React', 'Sass', 'Framer Motion', 'Contentful'], images: [ { url: '/images/portfolio/corporate-1.jpg', alt: '기업 웹사이트 메인페이지', isPrimary: true } ], clientName: '기술 기업 TechCorp', projectUrl: 'https://example-corp.demo', status: 'completed', featured: true, publishedAt: new Date('2024-03-10'), completedAt: new Date('2024-03-05'), isPublished: true, viewCount: 120, likes: 18 } ]; const mockServices = [ { _id: '1', name: '웹 개발', description: '현대적이고 반응형인 웹사이트와 웹 애플리케이션을 개발합니다. React, Node.js, MongoDB 등 최신 기술 스택을 활용하여 성능과 사용자 경험을 최적화합니다.', shortDescription: '현대적이고 반응형 웹사이트 및 웹 애플리케이션 개발', icon: 'fas fa-code', category: 'development', pricing: { basePrice: 500000, currency: 'KRW', priceType: 'project', priceRange: { min: 500000, max: 5000000 } }, featured: true, isActive: true }, { _id: '2', name: '모바일 앱 개발', description: 'iOS와 Android 플랫폼을 위한 네이티브 및 크로스플랫폼 모바일 애플리케이션을 개발합니다. React Native, Flutter 등을 활용하여 효율적인 개발을 진행합니다.', shortDescription: 'iOS/Android 네이티브 및 크로스플랫폼 앱 개발', icon: 'fas fa-mobile-alt', category: 'development', pricing: { basePrice: 800000, currency: 'KRW', priceType: 'project', priceRange: { min: 800000, max: 8000000 } }, featured: true, isActive: true }, { _id: '3', name: 'UI/UX 디자인', description: '사용자 중심의 직관적이고 아름다운 인터페이스를 디자인합니다. 사용자 경험 연구와 프로토타이핑을 통해 최적의 디자인 솔루션을 제공합니다.', shortDescription: '사용자 중심의 직관적이고 아름다운 인터페이스 디자인', icon: 'fas fa-palette', category: 'design', pricing: { basePrice: 300000, currency: 'KRW', priceType: 'project', priceRange: { min: 300000, max: 2000000 } }, featured: true, isActive: true }, { _id: '4', name: '디지털 마케팅', description: 'SEO, 소셜미디어 마케팅, 온라인 광고를 통해 디지털 마케팅 전략을 수립하고 실행합니다. 데이터 분석을 통한 지속적인 최적화를 제공합니다.', shortDescription: 'SEO, 소셜미디어, 온라인 광고를 통한 디지털 마케팅', icon: 'fas fa-chart-line', category: 'marketing', pricing: { basePrice: 200000, currency: 'KRW', priceType: 'project', priceRange: { min: 200000, max: 1500000 } }, featured: true, isActive: true } ]; const mockSettings = { siteName: 'SmartSolTech', siteDescription: '혁신적인 기술 솔루션으로 비즈니스의 성장을 지원합니다', contact: { email: 'info@smartsoltech.kr', phone: '+82-10-1234-5678', address: 'Seoul, South Korea' }, social: { facebook: 'https://facebook.com/smartsoltech', twitter: 'https://twitter.com/smartsoltech', linkedin: 'https://linkedin.com/company/smartsoltech', instagram: 'https://instagram.com/smartsoltech' } }; // Helper function for category names function getCategoryName(category) { const categoryNames = { 'web-development': '웹 개발', 'mobile-app': '모바일 앱', 'ui-ux-design': 'UI/UX 디자인', 'branding': '브랜딩', 'marketing': '디지털 마케팅' }; return categoryNames[category] || category; } // Routes app.get('/', (req, res) => { res.render('index', { title: 'SmartSolTech - Innovative Technology Solutions', settings: mockSettings, featuredPortfolio: mockPortfolio.filter(p => p.featured), featuredServices: mockServices.filter(s => s.featured), currentPage: 'home' }); }); app.get('/portfolio', (req, res) => { const category = req.query.category; let filteredPortfolio = mockPortfolio; if (category && category !== 'all') { filteredPortfolio = mockPortfolio.filter(p => p.category === category); } res.render('portfolio', { title: '포트폴리오 - SmartSolTech', portfolioItems: filteredPortfolio, currentPage: 'portfolio' }); }); app.get('/portfolio/:id', (req, res) => { const portfolio = mockPortfolio.find(p => p._id === req.params.id); if (!portfolio) { return res.status(404).render('error', { title: '404 - 페이지를 찾을 수 없습니다', message: '요청하신 포트폴리오 항목을 찾을 수 없습니다.' }); } const relatedProjects = mockPortfolio.filter(p => p._id !== portfolio._id && p.category === portfolio.category ).slice(0, 3); res.render('portfolio-detail', { title: `${portfolio.title} - 포트폴리오`, portfolio, relatedProjects }); }); app.get('/services', (req, res) => { res.render('services', { title: '서비스 - SmartSolTech', services: mockServices, currentPage: 'services' }); }); app.get('/contact', (req, res) => { res.render('contact', { title: '연락처 - SmartSolTech', settings: mockSettings, currentPage: 'contact' }); }); app.post('/contact', (req, res) => { // Simulate contact form processing console.log('Contact form submission:', req.body); req.flash('success', '문의가 성공적으로 접수되었습니다. 빠른 시일 내에 답변드리겠습니다.'); res.redirect('/contact'); }); app.get('/calculator', (req, res) => { res.render('calculator', { title: '비용 계산기 - SmartSolTech', services: mockServices, currentPage: 'calculator' }); }); // API Routes for calculator app.post('/api/calculator/estimate', (req, res) => { const { service, projectType, timeline, features } = req.body; // Simple calculation logic let basePrice = 500000; const selectedService = mockServices.find(s => s._id === service); if (selectedService) { basePrice = selectedService.pricing.basePrice; } // Apply multipliers based on project complexity const typeMultipliers = { 'simple': 1, 'medium': 1.5, 'complex': 2.5, 'enterprise': 4 }; const timelineMultipliers = { 'urgent': 1.5, 'normal': 1, 'flexible': 0.9 }; const typeMultiplier = typeMultipliers[projectType] || 1; const timelineMultiplier = timelineMultipliers[timeline] || 1; const featuresMultiplier = 1 + (features?.length || 0) * 0.2; const estimatedPrice = Math.round(basePrice * typeMultiplier * timelineMultiplier * featuresMultiplier); res.json({ success: true, estimate: { basePrice, estimatedPrice, breakdown: { basePrice, projectType: projectType, typeMultiplier, timeline, timelineMultiplier, features: features || [], featuresMultiplier } } }); }); // API Routes for portfolio interactions app.post('/api/portfolio/:id/like', (req, res) => { const portfolio = mockPortfolio.find(p => p._id === req.params.id); if (portfolio) { portfolio.likes = (portfolio.likes || 0) + 1; res.json({ success: true, likes: portfolio.likes }); } else { res.status(404).json({ success: false, message: 'Portfolio not found' }); } }); app.post('/api/portfolio/:id/view', (req, res) => { const portfolio = mockPortfolio.find(p => p._id === req.params.id); if (portfolio) { portfolio.viewCount = (portfolio.viewCount || 0) + 1; res.json({ success: true, viewCount: portfolio.viewCount }); } else { res.status(404).json({ success: false, message: 'Portfolio not found' }); } }); // Error handling app.use((req, res) => { res.status(404).render('error', { title: '404 - 페이지를 찾을 수 없습니다', message: '요청하신 페이지를 찾을 수 없습니다.' }); }); app.use((err, req, res, next) => { console.error(err.stack); res.status(500).render('error', { title: '500 - 서버 오류', message: '서버에서 오류가 발생했습니다.' }); }); // Start server app.listen(PORT, () => { console.log(`🚀 SmartSolTech Demo Server running on http://localhost:${PORT}`); console.log('📋 Available pages:'); console.log(' • Home: http://localhost:3000/'); console.log(' • Portfolio: http://localhost:3000/portfolio'); console.log(' • Services: http://localhost:3000/services'); console.log(' • Contact: http://localhost:3000/contact'); console.log(' • Calculator: http://localhost:3000/calculator'); console.log(''); console.log('💡 This is a demo version using mock data'); console.log('💾 To use with MongoDB, run: npm start'); }); module.exports = app;