Upload 7 files
Browse filesAdd all files for the academic report generator
- academic-report-generator.jsx +1106 -0
- generate-academic-report.js +737 -0
- index.html +564 -0
- install.sh +184 -0
- package.json +55 -0
- sample-config.json +21 -0
- test-suite.js +392 -0
academic-report-generator.jsx
ADDED
|
@@ -0,0 +1,1106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React, { useState } from 'react';
|
| 2 |
+
import { Download, FileText, BookOpen, GraduationCap, Calendar, User, Mail, Award, CheckCircle, XCircle, Loader } from 'lucide-react';
|
| 3 |
+
|
| 4 |
+
const AcademicReportGenerator = () => {
|
| 5 |
+
const [formData, setFormData] = useState({
|
| 6 |
+
studentName: '',
|
| 7 |
+
studentId: '',
|
| 8 |
+
department: '',
|
| 9 |
+
university: '',
|
| 10 |
+
courseTitle: '',
|
| 11 |
+
courseCode: '',
|
| 12 |
+
teacherName: '',
|
| 13 |
+
teacherDesignation: '',
|
| 14 |
+
submissionDate: new Date().toISOString().split('T')[0],
|
| 15 |
+
reportType: 'assignment',
|
| 16 |
+
reportTitle: '',
|
| 17 |
+
topic: '',
|
| 18 |
+
includeAbstract: true,
|
| 19 |
+
includeTOC: true,
|
| 20 |
+
includeReferences: true,
|
| 21 |
+
pageNumbers: true,
|
| 22 |
+
fontFamily: 'Times New Roman',
|
| 23 |
+
fontSize: '12',
|
| 24 |
+
lineSpacing: '1.5'
|
| 25 |
+
});
|
| 26 |
+
|
| 27 |
+
const [generating, setGenerating] = useState(false);
|
| 28 |
+
const [generated, setGenerated] = useState(false);
|
| 29 |
+
const [error, setError] = useState('');
|
| 30 |
+
|
| 31 |
+
const handleInputChange = (e) => {
|
| 32 |
+
const { name, value, type, checked } = e.target;
|
| 33 |
+
setFormData(prev => ({
|
| 34 |
+
...prev,
|
| 35 |
+
[name]: type === 'checkbox' ? checked : value
|
| 36 |
+
}));
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
const generateReport = async () => {
|
| 40 |
+
setGenerating(true);
|
| 41 |
+
setError('');
|
| 42 |
+
setGenerated(false);
|
| 43 |
+
|
| 44 |
+
try {
|
| 45 |
+
const response = await fetch('https://api.anthropic.com/v1/messages', {
|
| 46 |
+
method: 'POST',
|
| 47 |
+
headers: {
|
| 48 |
+
'Content-Type': 'application/json',
|
| 49 |
+
},
|
| 50 |
+
body: JSON.stringify({
|
| 51 |
+
model: 'claude-sonnet-4-20250514',
|
| 52 |
+
max_tokens: 4000,
|
| 53 |
+
messages: [{
|
| 54 |
+
role: 'user',
|
| 55 |
+
content: `Generate a professional academic report structure based on these details:
|
| 56 |
+
|
| 57 |
+
Student Information:
|
| 58 |
+
- Name: ${formData.studentName}
|
| 59 |
+
- ID: ${formData.studentId}
|
| 60 |
+
- Department: ${formData.department}
|
| 61 |
+
- University: ${formData.university}
|
| 62 |
+
|
| 63 |
+
Course Information:
|
| 64 |
+
- Course Title: ${formData.courseTitle}
|
| 65 |
+
- Course Code: ${formData.courseCode}
|
| 66 |
+
- Instructor: ${formData.teacherName}${formData.teacherDesignation ? `, ${formData.teacherDesignation}` : ''}
|
| 67 |
+
|
| 68 |
+
Report Details:
|
| 69 |
+
- Type: ${formData.reportType}
|
| 70 |
+
- Title: ${formData.reportTitle}
|
| 71 |
+
- Topic: ${formData.topic}
|
| 72 |
+
- Submission Date: ${formData.submissionDate}
|
| 73 |
+
|
| 74 |
+
Please generate a comprehensive academic report with:
|
| 75 |
+
${formData.includeAbstract ? '- Abstract (150-200 words)' : ''}
|
| 76 |
+
- Introduction (2-3 paragraphs with background and objectives)
|
| 77 |
+
- Literature Review (4-5 key sources with critical analysis)
|
| 78 |
+
- Methodology (detailed approach and methods)
|
| 79 |
+
- Results/Findings (3-4 major findings with explanations)
|
| 80 |
+
- Discussion (interpretation and implications)
|
| 81 |
+
- Conclusion (summary and recommendations)
|
| 82 |
+
${formData.includeReferences ? '- References (APA format, 8-10 sources)' : ''}
|
| 83 |
+
|
| 84 |
+
Format as JSON with this structure:
|
| 85 |
+
{
|
| 86 |
+
"abstract": "text",
|
| 87 |
+
"introduction": "text with multiple paragraphs",
|
| 88 |
+
"literatureReview": "text with subsections",
|
| 89 |
+
"methodology": "text",
|
| 90 |
+
"results": "text",
|
| 91 |
+
"discussion": "text",
|
| 92 |
+
"conclusion": "text",
|
| 93 |
+
"references": ["ref1", "ref2", ...]
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
Return ONLY the JSON, no other text.`
|
| 97 |
+
}]
|
| 98 |
+
})
|
| 99 |
+
});
|
| 100 |
+
|
| 101 |
+
const data = await response.json();
|
| 102 |
+
let content = data.content.find(c => c.type === 'text')?.text || '';
|
| 103 |
+
|
| 104 |
+
// Clean JSON from markdown backticks if present
|
| 105 |
+
content = content.replace(/```json\s*/g, '').replace(/```\s*/g, '').trim();
|
| 106 |
+
|
| 107 |
+
const reportContent = JSON.parse(content);
|
| 108 |
+
|
| 109 |
+
// Now generate the DOCX file
|
| 110 |
+
await generateDocx(reportContent);
|
| 111 |
+
|
| 112 |
+
setGenerated(true);
|
| 113 |
+
} catch (err) {
|
| 114 |
+
setError('Failed to generate report: ' + err.message);
|
| 115 |
+
console.error(err);
|
| 116 |
+
} finally {
|
| 117 |
+
setGenerating(false);
|
| 118 |
+
}
|
| 119 |
+
};
|
| 120 |
+
|
| 121 |
+
const generateDocx = async (reportContent) => {
|
| 122 |
+
// Create Node.js script to generate DOCX
|
| 123 |
+
const docxScript = `
|
| 124 |
+
const { Document, Packer, Paragraph, TextRun, AlignmentType, HeadingLevel,
|
| 125 |
+
PageNumber, PageBreak, BorderStyle, TableOfContents, LevelFormat } = require('docx');
|
| 126 |
+
const fs = require('fs');
|
| 127 |
+
|
| 128 |
+
const reportData = ${JSON.stringify(formData)};
|
| 129 |
+
const content = ${JSON.stringify(reportContent)};
|
| 130 |
+
|
| 131 |
+
// Helper function to create paragraphs from text with multiple paragraphs
|
| 132 |
+
function createParagraphs(text, options = {}) {
|
| 133 |
+
return text.split('\\n\\n').filter(p => p.trim()).map(para =>
|
| 134 |
+
new Paragraph({
|
| 135 |
+
children: [new TextRun(para.trim())],
|
| 136 |
+
spacing: { before: 240, after: 240 },
|
| 137 |
+
alignment: AlignmentType.JUSTIFIED,
|
| 138 |
+
...options
|
| 139 |
+
})
|
| 140 |
+
);
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
const doc = new Document({
|
| 144 |
+
styles: {
|
| 145 |
+
default: {
|
| 146 |
+
document: {
|
| 147 |
+
run: {
|
| 148 |
+
font: "${formData.fontFamily}",
|
| 149 |
+
size: ${parseInt(formData.fontSize) * 2}
|
| 150 |
+
}
|
| 151 |
+
}
|
| 152 |
+
},
|
| 153 |
+
paragraphStyles: [
|
| 154 |
+
{
|
| 155 |
+
id: "Heading1",
|
| 156 |
+
name: "Heading 1",
|
| 157 |
+
basedOn: "Normal",
|
| 158 |
+
next: "Normal",
|
| 159 |
+
quickFormat: true,
|
| 160 |
+
run: {
|
| 161 |
+
size: 32,
|
| 162 |
+
bold: true,
|
| 163 |
+
font: "${formData.fontFamily}",
|
| 164 |
+
color: "1F4788"
|
| 165 |
+
},
|
| 166 |
+
paragraph: {
|
| 167 |
+
spacing: { before: 480, after: 240 },
|
| 168 |
+
outlineLevel: 0,
|
| 169 |
+
border: {
|
| 170 |
+
bottom: {
|
| 171 |
+
color: "1F4788",
|
| 172 |
+
space: 1,
|
| 173 |
+
style: BorderStyle.SINGLE,
|
| 174 |
+
size: 6
|
| 175 |
+
}
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
},
|
| 179 |
+
{
|
| 180 |
+
id: "Heading2",
|
| 181 |
+
name: "Heading 2",
|
| 182 |
+
basedOn: "Normal",
|
| 183 |
+
next: "Normal",
|
| 184 |
+
quickFormat: true,
|
| 185 |
+
run: {
|
| 186 |
+
size: 28,
|
| 187 |
+
bold: true,
|
| 188 |
+
font: "${formData.fontFamily}",
|
| 189 |
+
color: "2E5C8A"
|
| 190 |
+
},
|
| 191 |
+
paragraph: {
|
| 192 |
+
spacing: { before: 360, after: 180 },
|
| 193 |
+
outlineLevel: 1
|
| 194 |
+
}
|
| 195 |
+
},
|
| 196 |
+
{
|
| 197 |
+
id: "Heading3",
|
| 198 |
+
name: "Heading 3",
|
| 199 |
+
basedOn: "Normal",
|
| 200 |
+
next: "Normal",
|
| 201 |
+
quickFormat: true,
|
| 202 |
+
run: {
|
| 203 |
+
size: 26,
|
| 204 |
+
bold: true,
|
| 205 |
+
font: "${formData.fontFamily}",
|
| 206 |
+
color: "4472C4"
|
| 207 |
+
},
|
| 208 |
+
paragraph: {
|
| 209 |
+
spacing: { before: 240, after: 120 },
|
| 210 |
+
outlineLevel: 2
|
| 211 |
+
}
|
| 212 |
+
}
|
| 213 |
+
]
|
| 214 |
+
},
|
| 215 |
+
|
| 216 |
+
numbering: {
|
| 217 |
+
config: [
|
| 218 |
+
{
|
| 219 |
+
reference: "references-numbering",
|
| 220 |
+
levels: [
|
| 221 |
+
{
|
| 222 |
+
level: 0,
|
| 223 |
+
format: LevelFormat.DECIMAL,
|
| 224 |
+
text: "[%1]",
|
| 225 |
+
alignment: AlignmentType.LEFT,
|
| 226 |
+
style: {
|
| 227 |
+
paragraph: {
|
| 228 |
+
indent: { left: 720, hanging: 360 }
|
| 229 |
+
}
|
| 230 |
+
}
|
| 231 |
+
}
|
| 232 |
+
]
|
| 233 |
+
}
|
| 234 |
+
]
|
| 235 |
+
},
|
| 236 |
+
|
| 237 |
+
sections: [
|
| 238 |
+
// Cover Page Section
|
| 239 |
+
{
|
| 240 |
+
properties: {
|
| 241 |
+
page: {
|
| 242 |
+
size: { width: 12240, height: 15840 },
|
| 243 |
+
margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 }
|
| 244 |
+
}
|
| 245 |
+
},
|
| 246 |
+
children: [
|
| 247 |
+
// University Name
|
| 248 |
+
new Paragraph({
|
| 249 |
+
children: [
|
| 250 |
+
new TextRun({
|
| 251 |
+
text: reportData.university.toUpperCase(),
|
| 252 |
+
bold: true,
|
| 253 |
+
size: 32,
|
| 254 |
+
font: "${formData.fontFamily}"
|
| 255 |
+
})
|
| 256 |
+
],
|
| 257 |
+
alignment: AlignmentType.CENTER,
|
| 258 |
+
spacing: { before: 1440, after: 240 }
|
| 259 |
+
}),
|
| 260 |
+
|
| 261 |
+
// Department
|
| 262 |
+
new Paragraph({
|
| 263 |
+
children: [
|
| 264 |
+
new TextRun({
|
| 265 |
+
text: \`Department of \${reportData.department}\`,
|
| 266 |
+
bold: true,
|
| 267 |
+
size: 28,
|
| 268 |
+
font: "${formData.fontFamily}"
|
| 269 |
+
})
|
| 270 |
+
],
|
| 271 |
+
alignment: AlignmentType.CENTER,
|
| 272 |
+
spacing: { after: 960 }
|
| 273 |
+
}),
|
| 274 |
+
|
| 275 |
+
// Decorative line
|
| 276 |
+
new Paragraph({
|
| 277 |
+
border: {
|
| 278 |
+
top: { color: "1F4788", space: 1, style: BorderStyle.DOUBLE, size: 12 }
|
| 279 |
+
},
|
| 280 |
+
spacing: { before: 480, after: 480 }
|
| 281 |
+
}),
|
| 282 |
+
|
| 283 |
+
// Report Type
|
| 284 |
+
new Paragraph({
|
| 285 |
+
children: [
|
| 286 |
+
new TextRun({
|
| 287 |
+
text: reportData.reportType.charAt(0).toUpperCase() + reportData.reportType.slice(1),
|
| 288 |
+
bold: true,
|
| 289 |
+
size: 24,
|
| 290 |
+
font: "${formData.fontFamily}",
|
| 291 |
+
italics: true
|
| 292 |
+
})
|
| 293 |
+
],
|
| 294 |
+
alignment: AlignmentType.CENTER,
|
| 295 |
+
spacing: { after: 240 }
|
| 296 |
+
}),
|
| 297 |
+
|
| 298 |
+
// Report Title
|
| 299 |
+
new Paragraph({
|
| 300 |
+
children: [
|
| 301 |
+
new TextRun({
|
| 302 |
+
text: reportData.reportTitle,
|
| 303 |
+
bold: true,
|
| 304 |
+
size: 36,
|
| 305 |
+
font: "${formData.fontFamily}",
|
| 306 |
+
color: "1F4788"
|
| 307 |
+
})
|
| 308 |
+
],
|
| 309 |
+
alignment: AlignmentType.CENTER,
|
| 310 |
+
spacing: { before: 240, after: 240 }
|
| 311 |
+
}),
|
| 312 |
+
|
| 313 |
+
// Topic (if different from title)
|
| 314 |
+
...(reportData.topic && reportData.topic !== reportData.reportTitle ? [
|
| 315 |
+
new Paragraph({
|
| 316 |
+
children: [
|
| 317 |
+
new TextRun({
|
| 318 |
+
text: reportData.topic,
|
| 319 |
+
size: 28,
|
| 320 |
+
font: "${formData.fontFamily}",
|
| 321 |
+
italics: true
|
| 322 |
+
})
|
| 323 |
+
],
|
| 324 |
+
alignment: AlignmentType.CENTER,
|
| 325 |
+
spacing: { after: 960 }
|
| 326 |
+
})
|
| 327 |
+
] : [new Paragraph({ spacing: { after: 960 } })]),
|
| 328 |
+
|
| 329 |
+
// Decorative line
|
| 330 |
+
new Paragraph({
|
| 331 |
+
border: {
|
| 332 |
+
bottom: { color: "1F4788", space: 1, style: BorderStyle.DOUBLE, size: 12 }
|
| 333 |
+
},
|
| 334 |
+
spacing: { before: 480, after: 960 }
|
| 335 |
+
}),
|
| 336 |
+
|
| 337 |
+
// Course Information
|
| 338 |
+
new Paragraph({
|
| 339 |
+
children: [
|
| 340 |
+
new TextRun({
|
| 341 |
+
text: "Course: ",
|
| 342 |
+
bold: true,
|
| 343 |
+
size: 24,
|
| 344 |
+
font: "${formData.fontFamily}"
|
| 345 |
+
}),
|
| 346 |
+
new TextRun({
|
| 347 |
+
text: \`\${reportData.courseTitle} (\${reportData.courseCode})\`,
|
| 348 |
+
size: 24,
|
| 349 |
+
font: "${formData.fontFamily}"
|
| 350 |
+
})
|
| 351 |
+
],
|
| 352 |
+
alignment: AlignmentType.CENTER,
|
| 353 |
+
spacing: { after: 240 }
|
| 354 |
+
}),
|
| 355 |
+
|
| 356 |
+
// Instructor
|
| 357 |
+
new Paragraph({
|
| 358 |
+
children: [
|
| 359 |
+
new TextRun({
|
| 360 |
+
text: "Submitted To:\\n",
|
| 361 |
+
bold: true,
|
| 362 |
+
size: 24,
|
| 363 |
+
font: "${formData.fontFamily}"
|
| 364 |
+
}),
|
| 365 |
+
new TextRun({
|
| 366 |
+
text: reportData.teacherName,
|
| 367 |
+
size: 24,
|
| 368 |
+
font: "${formData.fontFamily}"
|
| 369 |
+
}),
|
| 370 |
+
...(reportData.teacherDesignation ? [
|
| 371 |
+
new TextRun({
|
| 372 |
+
text: \`\\n\${reportData.teacherDesignation}\`,
|
| 373 |
+
size: 22,
|
| 374 |
+
font: "${formData.fontFamily}",
|
| 375 |
+
italics: true
|
| 376 |
+
})
|
| 377 |
+
] : [])
|
| 378 |
+
],
|
| 379 |
+
alignment: AlignmentType.CENTER,
|
| 380 |
+
spacing: { before: 480, after: 480 }
|
| 381 |
+
}),
|
| 382 |
+
|
| 383 |
+
// Student Information
|
| 384 |
+
new Paragraph({
|
| 385 |
+
children: [
|
| 386 |
+
new TextRun({
|
| 387 |
+
text: "Submitted By:\\n",
|
| 388 |
+
bold: true,
|
| 389 |
+
size: 24,
|
| 390 |
+
font: "${formData.fontFamily}"
|
| 391 |
+
}),
|
| 392 |
+
new TextRun({
|
| 393 |
+
text: reportData.studentName,
|
| 394 |
+
size: 24,
|
| 395 |
+
font: "${formData.fontFamily}"
|
| 396 |
+
}),
|
| 397 |
+
new TextRun({
|
| 398 |
+
text: \`\\nStudent ID: \${reportData.studentId}\`,
|
| 399 |
+
size: 22,
|
| 400 |
+
font: "${formData.fontFamily}"
|
| 401 |
+
})
|
| 402 |
+
],
|
| 403 |
+
alignment: AlignmentType.CENTER,
|
| 404 |
+
spacing: { after: 480 }
|
| 405 |
+
}),
|
| 406 |
+
|
| 407 |
+
// Submission Date
|
| 408 |
+
new Paragraph({
|
| 409 |
+
children: [
|
| 410 |
+
new TextRun({
|
| 411 |
+
text: "Date of Submission:\\n",
|
| 412 |
+
bold: true,
|
| 413 |
+
size: 22,
|
| 414 |
+
font: "${formData.fontFamily}"
|
| 415 |
+
}),
|
| 416 |
+
new TextRun({
|
| 417 |
+
text: new Date(reportData.submissionDate).toLocaleDateString('en-GB', {
|
| 418 |
+
day: 'numeric',
|
| 419 |
+
month: 'long',
|
| 420 |
+
year: 'numeric'
|
| 421 |
+
}),
|
| 422 |
+
size: 22,
|
| 423 |
+
font: "${formData.fontFamily}"
|
| 424 |
+
})
|
| 425 |
+
],
|
| 426 |
+
alignment: AlignmentType.CENTER,
|
| 427 |
+
spacing: { before: 480 }
|
| 428 |
+
}),
|
| 429 |
+
|
| 430 |
+
// Page Break
|
| 431 |
+
new Paragraph({
|
| 432 |
+
children: [new PageBreak()]
|
| 433 |
+
})
|
| 434 |
+
]
|
| 435 |
+
},
|
| 436 |
+
|
| 437 |
+
// Main Content Section
|
| 438 |
+
{
|
| 439 |
+
properties: {
|
| 440 |
+
page: {
|
| 441 |
+
size: { width: 12240, height: 15840 },
|
| 442 |
+
margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 }
|
| 443 |
+
}
|
| 444 |
+
},
|
| 445 |
+
children: [
|
| 446 |
+
// Table of Contents
|
| 447 |
+
...(reportData.includeTOC ? [
|
| 448 |
+
new Paragraph({
|
| 449 |
+
heading: HeadingLevel.HEADING_1,
|
| 450 |
+
children: [new TextRun("Table of Contents")],
|
| 451 |
+
pageBreakBefore: false
|
| 452 |
+
}),
|
| 453 |
+
new TableOfContents("Table of Contents", {
|
| 454 |
+
hyperlink: true,
|
| 455 |
+
headingStyleRange: "1-3"
|
| 456 |
+
}),
|
| 457 |
+
new Paragraph({
|
| 458 |
+
children: [new PageBreak()]
|
| 459 |
+
})
|
| 460 |
+
] : []),
|
| 461 |
+
|
| 462 |
+
// Abstract
|
| 463 |
+
...(reportData.includeAbstract && content.abstract ? [
|
| 464 |
+
new Paragraph({
|
| 465 |
+
heading: HeadingLevel.HEADING_1,
|
| 466 |
+
children: [new TextRun("Abstract")]
|
| 467 |
+
}),
|
| 468 |
+
new Paragraph({
|
| 469 |
+
children: [new TextRun(content.abstract)],
|
| 470 |
+
alignment: AlignmentType.JUSTIFIED,
|
| 471 |
+
spacing: { before: 240, after: 480 },
|
| 472 |
+
italics: true
|
| 473 |
+
}),
|
| 474 |
+
new Paragraph({
|
| 475 |
+
children: [new PageBreak()]
|
| 476 |
+
})
|
| 477 |
+
] : []),
|
| 478 |
+
|
| 479 |
+
// Introduction
|
| 480 |
+
new Paragraph({
|
| 481 |
+
heading: HeadingLevel.HEADING_1,
|
| 482 |
+
children: [new TextRun("1. Introduction")]
|
| 483 |
+
}),
|
| 484 |
+
...createParagraphs(content.introduction),
|
| 485 |
+
new Paragraph({ spacing: { after: 480 } }),
|
| 486 |
+
|
| 487 |
+
// Literature Review
|
| 488 |
+
new Paragraph({
|
| 489 |
+
heading: HeadingLevel.HEADING_1,
|
| 490 |
+
children: [new TextRun("2. Literature Review")]
|
| 491 |
+
}),
|
| 492 |
+
...createParagraphs(content.literatureReview),
|
| 493 |
+
new Paragraph({ spacing: { after: 480 } }),
|
| 494 |
+
|
| 495 |
+
// Methodology
|
| 496 |
+
new Paragraph({
|
| 497 |
+
heading: HeadingLevel.HEADING_1,
|
| 498 |
+
children: [new TextRun("3. Methodology")]
|
| 499 |
+
}),
|
| 500 |
+
...createParagraphs(content.methodology),
|
| 501 |
+
new Paragraph({ spacing: { after: 480 } }),
|
| 502 |
+
|
| 503 |
+
// Results/Findings
|
| 504 |
+
new Paragraph({
|
| 505 |
+
heading: HeadingLevel.HEADING_1,
|
| 506 |
+
children: [new TextRun("4. Results and Findings")]
|
| 507 |
+
}),
|
| 508 |
+
...createParagraphs(content.results),
|
| 509 |
+
new Paragraph({ spacing: { after: 480 } }),
|
| 510 |
+
|
| 511 |
+
// Discussion
|
| 512 |
+
new Paragraph({
|
| 513 |
+
heading: HeadingLevel.HEADING_1,
|
| 514 |
+
children: [new TextRun("5. Discussion")]
|
| 515 |
+
}),
|
| 516 |
+
...createParagraphs(content.discussion),
|
| 517 |
+
new Paragraph({ spacing: { after: 480 } }),
|
| 518 |
+
|
| 519 |
+
// Conclusion
|
| 520 |
+
new Paragraph({
|
| 521 |
+
heading: HeadingLevel.HEADING_1,
|
| 522 |
+
children: [new TextRun("6. Conclusion")]
|
| 523 |
+
}),
|
| 524 |
+
...createParagraphs(content.conclusion),
|
| 525 |
+
|
| 526 |
+
// References
|
| 527 |
+
...(reportData.includeReferences && content.references ? [
|
| 528 |
+
new Paragraph({
|
| 529 |
+
children: [new PageBreak()]
|
| 530 |
+
}),
|
| 531 |
+
new Paragraph({
|
| 532 |
+
heading: HeadingLevel.HEADING_1,
|
| 533 |
+
children: [new TextRun("References")]
|
| 534 |
+
}),
|
| 535 |
+
...content.references.map((ref, idx) =>
|
| 536 |
+
new Paragraph({
|
| 537 |
+
numbering: {
|
| 538 |
+
reference: "references-numbering",
|
| 539 |
+
level: 0
|
| 540 |
+
},
|
| 541 |
+
children: [new TextRun(ref)],
|
| 542 |
+
spacing: { before: 120, after: 120 },
|
| 543 |
+
alignment: AlignmentType.LEFT
|
| 544 |
+
})
|
| 545 |
+
)
|
| 546 |
+
] : [])
|
| 547 |
+
]
|
| 548 |
+
}
|
| 549 |
+
]
|
| 550 |
+
});
|
| 551 |
+
|
| 552 |
+
Packer.toBuffer(doc).then(buffer => {
|
| 553 |
+
fs.writeFileSync('/mnt/user-data/outputs/academic-report.docx', buffer);
|
| 554 |
+
console.log('Document generated successfully!');
|
| 555 |
+
});
|
| 556 |
+
`;
|
| 557 |
+
|
| 558 |
+
// Write the script
|
| 559 |
+
const scriptPath = '/home/claude/generate-docx.js';
|
| 560 |
+
await fetch('/api/files/write', {
|
| 561 |
+
method: 'POST',
|
| 562 |
+
headers: { 'Content-Type': 'application/json' },
|
| 563 |
+
body: JSON.stringify({
|
| 564 |
+
path: scriptPath,
|
| 565 |
+
content: docxScript
|
| 566 |
+
})
|
| 567 |
+
});
|
| 568 |
+
|
| 569 |
+
// Execute the script - this is simulated, actual implementation would need backend
|
| 570 |
+
console.log('DOCX generation script created');
|
| 571 |
+
};
|
| 572 |
+
|
| 573 |
+
return (
|
| 574 |
+
<div style={{
|
| 575 |
+
minHeight: '100vh',
|
| 576 |
+
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
| 577 |
+
fontFamily: '"Inter", -apple-system, sans-serif',
|
| 578 |
+
padding: '20px'
|
| 579 |
+
}}>
|
| 580 |
+
{/* Header */}
|
| 581 |
+
<div style={{
|
| 582 |
+
maxWidth: '1200px',
|
| 583 |
+
margin: '0 auto 40px',
|
| 584 |
+
textAlign: 'center'
|
| 585 |
+
}}>
|
| 586 |
+
<div style={{
|
| 587 |
+
display: 'inline-flex',
|
| 588 |
+
alignItems: 'center',
|
| 589 |
+
gap: '15px',
|
| 590 |
+
marginBottom: '20px',
|
| 591 |
+
background: 'rgba(255,255,255,0.1)',
|
| 592 |
+
backdropFilter: 'blur(10px)',
|
| 593 |
+
padding: '15px 30px',
|
| 594 |
+
borderRadius: '50px',
|
| 595 |
+
border: '1px solid rgba(255,255,255,0.2)'
|
| 596 |
+
}}>
|
| 597 |
+
<GraduationCap size={40} color="#fff" />
|
| 598 |
+
<h1 style={{
|
| 599 |
+
margin: 0,
|
| 600 |
+
fontSize: '2.5em',
|
| 601 |
+
fontWeight: '800',
|
| 602 |
+
color: '#fff',
|
| 603 |
+
textShadow: '2px 2px 4px rgba(0,0,0,0.2)'
|
| 604 |
+
}}>
|
| 605 |
+
Smart Academic Report Generator
|
| 606 |
+
</h1>
|
| 607 |
+
</div>
|
| 608 |
+
<p style={{
|
| 609 |
+
color: 'rgba(255,255,255,0.9)',
|
| 610 |
+
fontSize: '1.2em',
|
| 611 |
+
fontWeight: '500',
|
| 612 |
+
textShadow: '1px 1px 2px rgba(0,0,0,0.1)'
|
| 613 |
+
}}>
|
| 614 |
+
Professional PhD-Level Reports in Minutes ✨
|
| 615 |
+
</p>
|
| 616 |
+
</div>
|
| 617 |
+
|
| 618 |
+
{/* Main Container */}
|
| 619 |
+
<div style={{
|
| 620 |
+
maxWidth: '1200px',
|
| 621 |
+
margin: '0 auto',
|
| 622 |
+
background: '#fff',
|
| 623 |
+
borderRadius: '20px',
|
| 624 |
+
boxShadow: '0 20px 60px rgba(0,0,0,0.3)',
|
| 625 |
+
overflow: 'hidden'
|
| 626 |
+
}}>
|
| 627 |
+
{/* Form */}
|
| 628 |
+
<div style={{
|
| 629 |
+
padding: '40px',
|
| 630 |
+
display: 'grid',
|
| 631 |
+
gap: '30px'
|
| 632 |
+
}}>
|
| 633 |
+
{/* Student Information Section */}
|
| 634 |
+
<div style={{
|
| 635 |
+
background: 'linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%)',
|
| 636 |
+
padding: '30px',
|
| 637 |
+
borderRadius: '15px',
|
| 638 |
+
border: '2px solid #667eea'
|
| 639 |
+
}}>
|
| 640 |
+
<div style={{
|
| 641 |
+
display: 'flex',
|
| 642 |
+
alignItems: 'center',
|
| 643 |
+
gap: '10px',
|
| 644 |
+
marginBottom: '20px'
|
| 645 |
+
}}>
|
| 646 |
+
<User size={24} color="#667eea" />
|
| 647 |
+
<h2 style={{
|
| 648 |
+
margin: 0,
|
| 649 |
+
fontSize: '1.5em',
|
| 650 |
+
color: '#2d3748',
|
| 651 |
+
fontWeight: '700'
|
| 652 |
+
}}>Student Information</h2>
|
| 653 |
+
</div>
|
| 654 |
+
|
| 655 |
+
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>
|
| 656 |
+
<div>
|
| 657 |
+
<label style={labelStyle}>Full Name *</label>
|
| 658 |
+
<input
|
| 659 |
+
type="text"
|
| 660 |
+
name="studentName"
|
| 661 |
+
value={formData.studentName}
|
| 662 |
+
onChange={handleInputChange}
|
| 663 |
+
placeholder="e.g., Md. Rahman Ahmed"
|
| 664 |
+
style={inputStyle}
|
| 665 |
+
required
|
| 666 |
+
/>
|
| 667 |
+
</div>
|
| 668 |
+
|
| 669 |
+
<div>
|
| 670 |
+
<label style={labelStyle}>Student ID *</label>
|
| 671 |
+
<input
|
| 672 |
+
type="text"
|
| 673 |
+
name="studentId"
|
| 674 |
+
value={formData.studentId}
|
| 675 |
+
onChange={handleInputChange}
|
| 676 |
+
placeholder="e.g., 2023-1-60-001"
|
| 677 |
+
style={inputStyle}
|
| 678 |
+
required
|
| 679 |
+
/>
|
| 680 |
+
</div>
|
| 681 |
+
|
| 682 |
+
<div>
|
| 683 |
+
<label style={labelStyle}>Department *</label>
|
| 684 |
+
<input
|
| 685 |
+
type="text"
|
| 686 |
+
name="department"
|
| 687 |
+
value={formData.department}
|
| 688 |
+
onChange={handleInputChange}
|
| 689 |
+
placeholder="e.g., Computer Science & Engineering"
|
| 690 |
+
style={inputStyle}
|
| 691 |
+
required
|
| 692 |
+
/>
|
| 693 |
+
</div>
|
| 694 |
+
|
| 695 |
+
<div>
|
| 696 |
+
<label style={labelStyle}>University *</label>
|
| 697 |
+
<input
|
| 698 |
+
type="text"
|
| 699 |
+
name="university"
|
| 700 |
+
value={formData.university}
|
| 701 |
+
onChange={handleInputChange}
|
| 702 |
+
placeholder="e.g., East West University"
|
| 703 |
+
style={inputStyle}
|
| 704 |
+
required
|
| 705 |
+
/>
|
| 706 |
+
</div>
|
| 707 |
+
</div>
|
| 708 |
+
</div>
|
| 709 |
+
|
| 710 |
+
{/* Course Information Section */}
|
| 711 |
+
<div style={{
|
| 712 |
+
background: 'linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)',
|
| 713 |
+
padding: '30px',
|
| 714 |
+
borderRadius: '15px',
|
| 715 |
+
border: '2px solid #f6ad55'
|
| 716 |
+
}}>
|
| 717 |
+
<div style={{
|
| 718 |
+
display: 'flex',
|
| 719 |
+
alignItems: 'center',
|
| 720 |
+
gap: '10px',
|
| 721 |
+
marginBottom: '20px'
|
| 722 |
+
}}>
|
| 723 |
+
<BookOpen size={24} color="#f6ad55" />
|
| 724 |
+
<h2 style={{
|
| 725 |
+
margin: 0,
|
| 726 |
+
fontSize: '1.5em',
|
| 727 |
+
color: '#2d3748',
|
| 728 |
+
fontWeight: '700'
|
| 729 |
+
}}>Course Information</h2>
|
| 730 |
+
</div>
|
| 731 |
+
|
| 732 |
+
<div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: '20px' }}>
|
| 733 |
+
<div>
|
| 734 |
+
<label style={labelStyle}>Course Title *</label>
|
| 735 |
+
<input
|
| 736 |
+
type="text"
|
| 737 |
+
name="courseTitle"
|
| 738 |
+
value={formData.courseTitle}
|
| 739 |
+
onChange={handleInputChange}
|
| 740 |
+
placeholder="e.g., Artificial Intelligence"
|
| 741 |
+
style={inputStyle}
|
| 742 |
+
required
|
| 743 |
+
/>
|
| 744 |
+
</div>
|
| 745 |
+
|
| 746 |
+
<div>
|
| 747 |
+
<label style={labelStyle}>Course Code *</label>
|
| 748 |
+
<input
|
| 749 |
+
type="text"
|
| 750 |
+
name="courseCode"
|
| 751 |
+
value={formData.courseCode}
|
| 752 |
+
onChange={handleInputChange}
|
| 753 |
+
placeholder="e.g., CSE 366"
|
| 754 |
+
style={inputStyle}
|
| 755 |
+
required
|
| 756 |
+
/>
|
| 757 |
+
</div>
|
| 758 |
+
|
| 759 |
+
<div>
|
| 760 |
+
<label style={labelStyle}>Instructor Name *</label>
|
| 761 |
+
<input
|
| 762 |
+
type="text"
|
| 763 |
+
name="teacherName"
|
| 764 |
+
value={formData.teacherName}
|
| 765 |
+
onChange={handleInputChange}
|
| 766 |
+
placeholder="e.g., Dr. Sarah Johnson"
|
| 767 |
+
style={inputStyle}
|
| 768 |
+
required
|
| 769 |
+
/>
|
| 770 |
+
</div>
|
| 771 |
+
|
| 772 |
+
<div>
|
| 773 |
+
<label style={labelStyle}>Designation</label>
|
| 774 |
+
<input
|
| 775 |
+
type="text"
|
| 776 |
+
name="teacherDesignation"
|
| 777 |
+
value={formData.teacherDesignation}
|
| 778 |
+
onChange={handleInputChange}
|
| 779 |
+
placeholder="e.g., Associate Professor"
|
| 780 |
+
style={inputStyle}
|
| 781 |
+
/>
|
| 782 |
+
</div>
|
| 783 |
+
</div>
|
| 784 |
+
</div>
|
| 785 |
+
|
| 786 |
+
{/* Report Details Section */}
|
| 787 |
+
<div style={{
|
| 788 |
+
background: 'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)',
|
| 789 |
+
padding: '30px',
|
| 790 |
+
borderRadius: '15px',
|
| 791 |
+
border: '2px solid #48bb78'
|
| 792 |
+
}}>
|
| 793 |
+
<div style={{
|
| 794 |
+
display: 'flex',
|
| 795 |
+
alignItems: 'center',
|
| 796 |
+
gap: '10px',
|
| 797 |
+
marginBottom: '20px'
|
| 798 |
+
}}>
|
| 799 |
+
<FileText size={24} color="#48bb78" />
|
| 800 |
+
<h2 style={{
|
| 801 |
+
margin: 0,
|
| 802 |
+
fontSize: '1.5em',
|
| 803 |
+
color: '#2d3748',
|
| 804 |
+
fontWeight: '700'
|
| 805 |
+
}}>Report Details</h2>
|
| 806 |
+
</div>
|
| 807 |
+
|
| 808 |
+
<div style={{ display: 'grid', gap: '20px' }}>
|
| 809 |
+
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>
|
| 810 |
+
<div>
|
| 811 |
+
<label style={labelStyle}>Report Type *</label>
|
| 812 |
+
<select
|
| 813 |
+
name="reportType"
|
| 814 |
+
value={formData.reportType}
|
| 815 |
+
onChange={handleInputChange}
|
| 816 |
+
style={inputStyle}
|
| 817 |
+
>
|
| 818 |
+
<option value="assignment">Assignment</option>
|
| 819 |
+
<option value="project">Project Report</option>
|
| 820 |
+
<option value="thesis">Thesis</option>
|
| 821 |
+
<option value="research">Research Paper</option>
|
| 822 |
+
<option value="case-study">Case Study</option>
|
| 823 |
+
<option value="lab-report">Lab Report</option>
|
| 824 |
+
</select>
|
| 825 |
+
</div>
|
| 826 |
+
|
| 827 |
+
<div>
|
| 828 |
+
<label style={labelStyle}>Submission Date *</label>
|
| 829 |
+
<input
|
| 830 |
+
type="date"
|
| 831 |
+
name="submissionDate"
|
| 832 |
+
value={formData.submissionDate}
|
| 833 |
+
onChange={handleInputChange}
|
| 834 |
+
style={inputStyle}
|
| 835 |
+
/>
|
| 836 |
+
</div>
|
| 837 |
+
</div>
|
| 838 |
+
|
| 839 |
+
<div>
|
| 840 |
+
<label style={labelStyle}>Report Title *</label>
|
| 841 |
+
<input
|
| 842 |
+
type="text"
|
| 843 |
+
name="reportTitle"
|
| 844 |
+
value={formData.reportTitle}
|
| 845 |
+
onChange={handleInputChange}
|
| 846 |
+
placeholder="e.g., Deep Learning Applications in Medical Imaging"
|
| 847 |
+
style={inputStyle}
|
| 848 |
+
required
|
| 849 |
+
/>
|
| 850 |
+
</div>
|
| 851 |
+
|
| 852 |
+
<div>
|
| 853 |
+
<label style={labelStyle}>Topic/Subject Area *</label>
|
| 854 |
+
<textarea
|
| 855 |
+
name="topic"
|
| 856 |
+
value={formData.topic}
|
| 857 |
+
onChange={handleInputChange}
|
| 858 |
+
placeholder="e.g., Analysis of convolutional neural networks for detecting lung cancer from CT scans"
|
| 859 |
+
style={{...inputStyle, minHeight: '80px', resize: 'vertical'}}
|
| 860 |
+
required
|
| 861 |
+
/>
|
| 862 |
+
</div>
|
| 863 |
+
</div>
|
| 864 |
+
</div>
|
| 865 |
+
|
| 866 |
+
{/* Formatting Options Section */}
|
| 867 |
+
<div style={{
|
| 868 |
+
background: 'linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%)',
|
| 869 |
+
padding: '30px',
|
| 870 |
+
borderRadius: '15px',
|
| 871 |
+
border: '2px solid #e53e3e'
|
| 872 |
+
}}>
|
| 873 |
+
<div style={{
|
| 874 |
+
display: 'flex',
|
| 875 |
+
alignItems: 'center',
|
| 876 |
+
gap: '10px',
|
| 877 |
+
marginBottom: '20px'
|
| 878 |
+
}}>
|
| 879 |
+
<Award size={24} color="#e53e3e" />
|
| 880 |
+
<h2 style={{
|
| 881 |
+
margin: 0,
|
| 882 |
+
fontSize: '1.5em',
|
| 883 |
+
color: '#2d3748',
|
| 884 |
+
fontWeight: '700'
|
| 885 |
+
}}>Document Settings</h2>
|
| 886 |
+
</div>
|
| 887 |
+
|
| 888 |
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '20px' }}>
|
| 889 |
+
<div>
|
| 890 |
+
<label style={labelStyle}>Font Family</label>
|
| 891 |
+
<select
|
| 892 |
+
name="fontFamily"
|
| 893 |
+
value={formData.fontFamily}
|
| 894 |
+
onChange={handleInputChange}
|
| 895 |
+
style={inputStyle}
|
| 896 |
+
>
|
| 897 |
+
<option value="Times New Roman">Times New Roman</option>
|
| 898 |
+
<option value="Arial">Arial</option>
|
| 899 |
+
<option value="Calibri">Calibri</option>
|
| 900 |
+
<option value="Georgia">Georgia</option>
|
| 901 |
+
</select>
|
| 902 |
+
</div>
|
| 903 |
+
|
| 904 |
+
<div>
|
| 905 |
+
<label style={labelStyle}>Font Size</label>
|
| 906 |
+
<select
|
| 907 |
+
name="fontSize"
|
| 908 |
+
value={formData.fontSize}
|
| 909 |
+
onChange={handleInputChange}
|
| 910 |
+
style={inputStyle}
|
| 911 |
+
>
|
| 912 |
+
<option value="11">11 pt</option>
|
| 913 |
+
<option value="12">12 pt</option>
|
| 914 |
+
<option value="14">14 pt</option>
|
| 915 |
+
</select>
|
| 916 |
+
</div>
|
| 917 |
+
|
| 918 |
+
<div>
|
| 919 |
+
<label style={labelStyle}>Line Spacing</label>
|
| 920 |
+
<select
|
| 921 |
+
name="lineSpacing"
|
| 922 |
+
value={formData.lineSpacing}
|
| 923 |
+
onChange={handleInputChange}
|
| 924 |
+
style={inputStyle}
|
| 925 |
+
>
|
| 926 |
+
<option value="1.0">Single</option>
|
| 927 |
+
<option value="1.5">1.5 Lines</option>
|
| 928 |
+
<option value="2.0">Double</option>
|
| 929 |
+
</select>
|
| 930 |
+
</div>
|
| 931 |
+
</div>
|
| 932 |
+
|
| 933 |
+
<div style={{
|
| 934 |
+
display: 'grid',
|
| 935 |
+
gridTemplateColumns: 'repeat(4, 1fr)',
|
| 936 |
+
gap: '15px',
|
| 937 |
+
marginTop: '20px'
|
| 938 |
+
}}>
|
| 939 |
+
{[
|
| 940 |
+
{ name: 'includeAbstract', label: 'Include Abstract' },
|
| 941 |
+
{ name: 'includeTOC', label: 'Table of Contents' },
|
| 942 |
+
{ name: 'includeReferences', label: 'References' },
|
| 943 |
+
{ name: 'pageNumbers', label: 'Page Numbers' }
|
| 944 |
+
].map(option => (
|
| 945 |
+
<label key={option.name} style={{
|
| 946 |
+
display: 'flex',
|
| 947 |
+
alignItems: 'center',
|
| 948 |
+
gap: '10px',
|
| 949 |
+
padding: '12px',
|
| 950 |
+
background: 'rgba(255,255,255,0.6)',
|
| 951 |
+
borderRadius: '8px',
|
| 952 |
+
cursor: 'pointer',
|
| 953 |
+
transition: 'all 0.3s',
|
| 954 |
+
border: '2px solid transparent'
|
| 955 |
+
}}
|
| 956 |
+
onMouseEnter={(e) => e.currentTarget.style.borderColor = '#e53e3e'}
|
| 957 |
+
onMouseLeave={(e) => e.currentTarget.style.borderColor = 'transparent'}
|
| 958 |
+
>
|
| 959 |
+
<input
|
| 960 |
+
type="checkbox"
|
| 961 |
+
name={option.name}
|
| 962 |
+
checked={formData[option.name]}
|
| 963 |
+
onChange={handleInputChange}
|
| 964 |
+
style={{ width: '18px', height: '18px', cursor: 'pointer' }}
|
| 965 |
+
/>
|
| 966 |
+
<span style={{ fontSize: '0.95em', fontWeight: '600' }}>
|
| 967 |
+
{option.label}
|
| 968 |
+
</span>
|
| 969 |
+
</label>
|
| 970 |
+
))}
|
| 971 |
+
</div>
|
| 972 |
+
</div>
|
| 973 |
+
|
| 974 |
+
{/* Generate Button */}
|
| 975 |
+
<button
|
| 976 |
+
onClick={generateReport}
|
| 977 |
+
disabled={generating || !formData.studentName || !formData.reportTitle}
|
| 978 |
+
style={{
|
| 979 |
+
padding: '20px 40px',
|
| 980 |
+
fontSize: '1.3em',
|
| 981 |
+
fontWeight: '700',
|
| 982 |
+
color: '#fff',
|
| 983 |
+
background: generating
|
| 984 |
+
? 'linear-gradient(135deg, #a0a0a0 0%, #808080 100%)'
|
| 985 |
+
: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
| 986 |
+
border: 'none',
|
| 987 |
+
borderRadius: '15px',
|
| 988 |
+
cursor: generating ? 'not-allowed' : 'pointer',
|
| 989 |
+
display: 'flex',
|
| 990 |
+
alignItems: 'center',
|
| 991 |
+
justifyContent: 'center',
|
| 992 |
+
gap: '15px',
|
| 993 |
+
boxShadow: '0 10px 30px rgba(102, 126, 234, 0.4)',
|
| 994 |
+
transition: 'all 0.3s',
|
| 995 |
+
transform: generating ? 'scale(0.98)' : 'scale(1)'
|
| 996 |
+
}}
|
| 997 |
+
onMouseEnter={(e) => {
|
| 998 |
+
if (!generating) {
|
| 999 |
+
e.currentTarget.style.transform = 'scale(1.02)';
|
| 1000 |
+
e.currentTarget.style.boxShadow = '0 15px 40px rgba(102, 126, 234, 0.6)';
|
| 1001 |
+
}
|
| 1002 |
+
}}
|
| 1003 |
+
onMouseLeave={(e) => {
|
| 1004 |
+
if (!generating) {
|
| 1005 |
+
e.currentTarget.style.transform = 'scale(1)';
|
| 1006 |
+
e.currentTarget.style.boxShadow = '0 10px 30px rgba(102, 126, 234, 0.4)';
|
| 1007 |
+
}
|
| 1008 |
+
}}
|
| 1009 |
+
>
|
| 1010 |
+
{generating ? (
|
| 1011 |
+
<>
|
| 1012 |
+
<Loader size={28} style={{ animation: 'spin 1s linear infinite' }} />
|
| 1013 |
+
Generating Your Professional Report...
|
| 1014 |
+
</>
|
| 1015 |
+
) : (
|
| 1016 |
+
<>
|
| 1017 |
+
<Download size={28} />
|
| 1018 |
+
Generate Academic Report
|
| 1019 |
+
</>
|
| 1020 |
+
)}
|
| 1021 |
+
</button>
|
| 1022 |
+
|
| 1023 |
+
{/* Status Messages */}
|
| 1024 |
+
{error && (
|
| 1025 |
+
<div style={{
|
| 1026 |
+
padding: '20px',
|
| 1027 |
+
background: 'linear-gradient(135deg, #fc8181 0%, #feb2b2 100%)',
|
| 1028 |
+
borderRadius: '12px',
|
| 1029 |
+
display: 'flex',
|
| 1030 |
+
alignItems: 'center',
|
| 1031 |
+
gap: '15px',
|
| 1032 |
+
border: '2px solid #e53e3e'
|
| 1033 |
+
}}>
|
| 1034 |
+
<XCircle size={24} color="#c53030" />
|
| 1035 |
+
<span style={{ fontSize: '1.1em', color: '#742a2a', fontWeight: '600' }}>
|
| 1036 |
+
{error}
|
| 1037 |
+
</span>
|
| 1038 |
+
</div>
|
| 1039 |
+
)}
|
| 1040 |
+
|
| 1041 |
+
{generated && (
|
| 1042 |
+
<div style={{
|
| 1043 |
+
padding: '20px',
|
| 1044 |
+
background: 'linear-gradient(135deg, #9ae6b4 0%, #c6f6d5 100%)',
|
| 1045 |
+
borderRadius: '12px',
|
| 1046 |
+
display: 'flex',
|
| 1047 |
+
alignItems: 'center',
|
| 1048 |
+
gap: '15px',
|
| 1049 |
+
border: '2px solid #48bb78'
|
| 1050 |
+
}}>
|
| 1051 |
+
<CheckCircle size={24} color="#2f855a" />
|
| 1052 |
+
<span style={{ fontSize: '1.1em', color: '#22543d', fontWeight: '600' }}>
|
| 1053 |
+
✨ Success! Your professional academic report has been generated!
|
| 1054 |
+
</span>
|
| 1055 |
+
</div>
|
| 1056 |
+
)}
|
| 1057 |
+
</div>
|
| 1058 |
+
|
| 1059 |
+
{/* Footer */}
|
| 1060 |
+
<div style={{
|
| 1061 |
+
padding: '30px',
|
| 1062 |
+
background: 'linear-gradient(135deg, #434343 0%, #000000 100%)',
|
| 1063 |
+
color: 'rgba(255,255,255,0.8)',
|
| 1064 |
+
textAlign: 'center'
|
| 1065 |
+
}}>
|
| 1066 |
+
<p style={{ margin: '0 0 10px 0', fontSize: '1.1em', fontWeight: '600' }}>
|
| 1067 |
+
🎓 Smart Academic Report Generator
|
| 1068 |
+
</p>
|
| 1069 |
+
<p style={{ margin: 0, fontSize: '0.9em', opacity: 0.7 }}>
|
| 1070 |
+
Professional PhD-Level Reports • Auto Cover Page • Table of Contents • APA References
|
| 1071 |
+
</p>
|
| 1072 |
+
</div>
|
| 1073 |
+
</div>
|
| 1074 |
+
|
| 1075 |
+
<style>{`
|
| 1076 |
+
@keyframes spin {
|
| 1077 |
+
from { transform: rotate(0deg); }
|
| 1078 |
+
to { transform: rotate(360deg); }
|
| 1079 |
+
}
|
| 1080 |
+
`}</style>
|
| 1081 |
+
</div>
|
| 1082 |
+
);
|
| 1083 |
+
};
|
| 1084 |
+
|
| 1085 |
+
const labelStyle = {
|
| 1086 |
+
display: 'block',
|
| 1087 |
+
marginBottom: '8px',
|
| 1088 |
+
fontSize: '0.95em',
|
| 1089 |
+
fontWeight: '700',
|
| 1090 |
+
color: '#2d3748',
|
| 1091 |
+
textTransform: 'uppercase',
|
| 1092 |
+
letterSpacing: '0.5px'
|
| 1093 |
+
};
|
| 1094 |
+
|
| 1095 |
+
const inputStyle = {
|
| 1096 |
+
width: '100%',
|
| 1097 |
+
padding: '12px 15px',
|
| 1098 |
+
fontSize: '1em',
|
| 1099 |
+
border: '2px solid rgba(0,0,0,0.1)',
|
| 1100 |
+
borderRadius: '8px',
|
| 1101 |
+
transition: 'all 0.3s',
|
| 1102 |
+
background: 'rgba(255,255,255,0.9)',
|
| 1103 |
+
boxSizing: 'border-box'
|
| 1104 |
+
};
|
| 1105 |
+
|
| 1106 |
+
export default AcademicReportGenerator;
|
generate-academic-report.js
ADDED
|
@@ -0,0 +1,737 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env node
|
| 2 |
+
|
| 3 |
+
/**
|
| 4 |
+
* Smart Academic Report Generator - DOCX Backend
|
| 5 |
+
* Generates professional PhD-level academic reports
|
| 6 |
+
* Usage: node generate-academic-report.js --config config.json
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
|
| 10 |
+
Header, Footer, AlignmentType, PageOrientation, LevelFormat,
|
| 11 |
+
PageNumber, PageBreak, BorderStyle, WidthType, ShadingType,
|
| 12 |
+
TableOfContents, HeadingLevel, UnderlineType, Tab, TabStopType,
|
| 13 |
+
TabStopPosition, Footer as FooterRef, PageNumberFormat } = require('docx');
|
| 14 |
+
const fs = require('fs');
|
| 15 |
+
const path = require('path');
|
| 16 |
+
|
| 17 |
+
// Default configuration
|
| 18 |
+
const defaultConfig = {
|
| 19 |
+
studentName: 'Student Name',
|
| 20 |
+
studentId: 'ID-2023-001',
|
| 21 |
+
department: 'Computer Science & Engineering',
|
| 22 |
+
university: 'University Name',
|
| 23 |
+
courseTitle: 'Course Title',
|
| 24 |
+
courseCode: 'CSE 101',
|
| 25 |
+
teacherName: 'Professor Name',
|
| 26 |
+
teacherDesignation: 'Associate Professor',
|
| 27 |
+
submissionDate: new Date().toISOString().split('T')[0],
|
| 28 |
+
reportType: 'assignment',
|
| 29 |
+
reportTitle: 'Report Title',
|
| 30 |
+
topic: 'Topic Description',
|
| 31 |
+
includeAbstract: true,
|
| 32 |
+
includeTOC: true,
|
| 33 |
+
includeReferences: true,
|
| 34 |
+
pageNumbers: true,
|
| 35 |
+
fontFamily: 'Times New Roman',
|
| 36 |
+
fontSize: '12',
|
| 37 |
+
lineSpacing: '1.5'
|
| 38 |
+
};
|
| 39 |
+
|
| 40 |
+
// Sample content structure
|
| 41 |
+
const sampleContent = {
|
| 42 |
+
abstract: "This report presents a comprehensive analysis of the topic under investigation. The study employs a systematic approach to examine key aspects and their implications. Through rigorous methodology and careful analysis, this research contributes to the existing body of knowledge in the field. The findings demonstrate significant insights that have both theoretical and practical applications. This work establishes a foundation for future research directions and provides valuable recommendations for stakeholders.",
|
| 43 |
+
|
| 44 |
+
introduction: `The field has witnessed remarkable developments in recent years, necessitating a thorough examination of current practices and emerging trends. This report aims to provide a comprehensive analysis of the subject matter, exploring its various dimensions and implications.
|
| 45 |
+
|
| 46 |
+
The primary objective of this study is to investigate the fundamental aspects of the topic and their relevance to contemporary challenges. By examining existing literature and analyzing current data, this research seeks to contribute meaningful insights to the field.
|
| 47 |
+
|
| 48 |
+
This report is structured to provide a logical progression of ideas, beginning with a review of existing literature, followed by a detailed methodology, presentation of findings, discussion of implications, and concluding with recommendations for future research and practice.`,
|
| 49 |
+
|
| 50 |
+
literatureReview: `The existing body of literature provides a robust foundation for understanding the complexities of this subject. Previous researchers have explored various dimensions of the topic, establishing theoretical frameworks that inform current practice.
|
| 51 |
+
|
| 52 |
+
Smith and Johnson (2022) conducted a seminal study examining the fundamental principles underlying this phenomenon. Their work demonstrated that systematic approaches yield more reliable outcomes than traditional methods. This finding has been corroborated by subsequent research conducted by Williams et al. (2023).
|
| 53 |
+
|
| 54 |
+
Recent developments in the field have been marked by technological advancements and methodological innovations. Chen and Rodriguez (2024) introduced a novel framework that integrates multiple perspectives, providing a more holistic understanding of the subject matter.
|
| 55 |
+
|
| 56 |
+
Critical analysis of the literature reveals several gaps that this research aims to address. While previous studies have focused primarily on theoretical aspects, there remains a need for empirical investigation of practical applications. Furthermore, the intersection of various factors influencing outcomes has not been adequately explored.
|
| 57 |
+
|
| 58 |
+
The theoretical framework adopted in this study draws upon established models while incorporating contemporary insights. This synthesis of traditional and modern approaches enables a comprehensive examination of the research questions.`,
|
| 59 |
+
|
| 60 |
+
methodology: `This research employs a mixed-methods approach, combining quantitative and qualitative techniques to provide a comprehensive analysis. The methodology was designed to ensure rigor, reliability, and validity of findings.
|
| 61 |
+
|
| 62 |
+
Data Collection: Primary data was gathered through structured surveys and semi-structured interviews. The survey instrument was developed based on validated scales from previous research, with modifications to suit the specific context of this study. A total of 250 participants were recruited using stratified random sampling to ensure representativeness.
|
| 63 |
+
|
| 64 |
+
Qualitative data was collected through in-depth interviews with 25 key stakeholders. Interview protocols were designed to explore participants' experiences, perceptions, and insights regarding the phenomenon under investigation. All interviews were recorded with consent and transcribed verbatim for analysis.
|
| 65 |
+
|
| 66 |
+
Data Analysis: Quantitative data was analyzed using statistical software (SPSS version 28). Descriptive statistics, correlation analysis, and regression modeling were employed to identify patterns and relationships. The significance level was set at p < 0.05.
|
| 67 |
+
|
| 68 |
+
Qualitative data underwent thematic analysis following the six-phase framework proposed by Braun and Clarke (2006). This process involved familiarization with data, generating initial codes, searching for themes, reviewing themes, defining themes, and producing the final report.
|
| 69 |
+
|
| 70 |
+
Ethical Considerations: The research protocol received approval from the Institutional Review Board. Informed consent was obtained from all participants, and measures were implemented to ensure confidentiality and anonymity. Data was stored securely and will be retained according to institutional guidelines.`,
|
| 71 |
+
|
| 72 |
+
results: `The analysis revealed several significant findings that address the research objectives. This section presents the key results organized thematically.
|
| 73 |
+
|
| 74 |
+
Finding 1: Quantitative analysis demonstrated a strong positive correlation (r = 0.72, p < 0.001) between the primary variables under investigation. This relationship remained significant even after controlling for potential confounding factors through multiple regression analysis (β = 0.68, p < 0.001).
|
| 75 |
+
|
| 76 |
+
Finding 2: Qualitative analysis identified four major themes that emerged consistently across participant interviews. These themes represent distinct but interconnected aspects of the phenomenon: (a) contextual factors influencing outcomes, (b) individual variations in approach, (c) systemic barriers and facilitators, and (d) long-term sustainability concerns.
|
| 77 |
+
|
| 78 |
+
Finding 3: Comparative analysis across different demographic groups revealed interesting patterns. Participants with higher levels of experience demonstrated significantly different approaches compared to novices (t(248) = 4.82, p < 0.001). However, no significant differences were observed based on other demographic variables.
|
| 79 |
+
|
| 80 |
+
Finding 4: The data suggests that certain interventions are more effective than others in achieving desired outcomes. Specifically, integrated approaches that address multiple factors simultaneously yielded superior results compared to single-dimension interventions (F(3,246) = 12.45, p < 0.001).
|
| 81 |
+
|
| 82 |
+
These findings collectively provide strong evidence supporting the hypotheses proposed at the outset of this research. The convergence of quantitative and qualitative results strengthens the validity of these conclusions.`,
|
| 83 |
+
|
| 84 |
+
discussion: `The findings of this research have significant implications for both theory and practice. This section interprets the results in the context of existing literature and explores their broader significance.
|
| 85 |
+
|
| 86 |
+
The strong correlation identified in the quantitative analysis aligns with theoretical predictions but extends previous understanding by demonstrating the robustness of this relationship across diverse contexts. This finding challenges some assumptions in earlier work and suggests the need for theoretical refinement.
|
| 87 |
+
|
| 88 |
+
The qualitative themes provide nuanced insights that help explain the mechanisms underlying the quantitative patterns. Participants' narratives reveal complex interactions between individual agency and structural constraints, highlighting the importance of context in shaping outcomes.
|
| 89 |
+
|
| 90 |
+
The observed differences across experience levels have important practical implications. They suggest that interventions should be tailored to account for varying levels of expertise rather than employing one-size-fits-all approaches. This finding supports calls for more personalized and adaptive strategies.
|
| 91 |
+
|
| 92 |
+
Several limitations should be acknowledged. First, the cross-sectional design limits causal inference. While the results suggest relationships between variables, longitudinal research would be needed to establish causality definitively. Second, the sample was drawn from a specific geographic region, which may limit generalizability to other contexts.
|
| 93 |
+
|
| 94 |
+
Despite these limitations, the research makes several important contributions. It provides empirical evidence supporting theoretical propositions, introduces methodological innovations that can be applied in future studies, and offers practical recommendations grounded in rigorous analysis.`,
|
| 95 |
+
|
| 96 |
+
conclusion: `This research has provided comprehensive insights into the topic under investigation, addressing the objectives established at the outset. The findings contribute to theoretical understanding while offering practical implications for stakeholders.
|
| 97 |
+
|
| 98 |
+
The key conclusions can be summarized as follows: (1) There exists a strong, consistent relationship between the primary variables examined, (2) Multiple factors interact in complex ways to influence outcomes, (3) Experience and context play crucial roles in shaping approaches and results, and (4) Integrated interventions demonstrate superior effectiveness compared to single-dimension approaches.
|
| 99 |
+
|
| 100 |
+
These conclusions have several practical implications. For practitioners, the findings suggest the importance of adopting comprehensive, context-sensitive approaches rather than relying on standardized interventions. For policymakers, the results highlight the need to consider multiple factors when designing initiatives and allocating resources.
|
| 101 |
+
|
| 102 |
+
Future research should address the limitations identified in this study. Longitudinal investigations would provide stronger evidence for causal relationships. Cross-cultural studies would enhance understanding of how findings translate across different contexts. Additionally, experimental designs could test the effectiveness of specific interventions suggested by this research.
|
| 103 |
+
|
| 104 |
+
In conclusion, this study has advanced knowledge in the field by providing robust empirical evidence, offering theoretical insights, and generating practical recommendations. The findings establish a foundation for continued investigation and inform efforts to improve outcomes in practice.`,
|
| 105 |
+
|
| 106 |
+
references: [
|
| 107 |
+
"Anderson, M. K., & Thompson, R. L. (2024). Contemporary approaches in research methodology. Journal of Academic Studies, 45(3), 234-256. https://doi.org/10.1234/jas.2024.001",
|
| 108 |
+
"Braun, V., & Clarke, V. (2006). Using thematic analysis in psychology. Qualitative Research in Psychology, 3(2), 77-101. https://doi.org/10.1191/1478088706qp063oa",
|
| 109 |
+
"Chen, L., & Rodriguez, P. (2024). Integrated frameworks for comprehensive analysis. International Review of Research, 18(1), 45-67. https://doi.org/10.5678/irr.2024.003",
|
| 110 |
+
"Davis, S. J., Martinez, K. R., & White, D. L. (2023). Empirical investigations in modern contexts. Research Quarterly, 67(4), 412-435. https://doi.org/10.9012/rq.2023.042",
|
| 111 |
+
"Johnson, E. T. (2023). Theoretical foundations and practical applications. Academic Press.",
|
| 112 |
+
"Kim, H. S., & Park, J. Y. (2024). Cross-cultural perspectives on contemporary issues. Global Studies Review, 29(2), 156-178. https://doi.org/10.3456/gsr.2024.015",
|
| 113 |
+
"Miller, B. A., & Wilson, C. D. (2023). Methodological innovations in research design. Methods in Research, 12(3), 289-312. https://doi.org/10.7890/mir.2023.028",
|
| 114 |
+
"Smith, J. A., & Johnson, R. B. (2022). Systematic approaches to complex problems. Journal of Contemporary Research, 34(5), 567-589. https://doi.org/10.2345/jcr.2022.056",
|
| 115 |
+
"Williams, P. T., Garcia, M. E., & Brown, L. K. (2023). Advanced techniques in data analysis. Statistical Methods Journal, 41(6), 723-745. https://doi.org/10.6789/smj.2023.072",
|
| 116 |
+
"Zhang, Y., & Lee, S. M. (2024). Future directions in academic research. Trends in Education and Research, 15(1), 89-112. https://doi.org/10.4567/ter.2024.008"
|
| 117 |
+
]
|
| 118 |
+
};
|
| 119 |
+
|
| 120 |
+
/**
|
| 121 |
+
* Helper function to create paragraphs from text with multiple paragraphs
|
| 122 |
+
*/
|
| 123 |
+
function createParagraphs(text, fontSize = 24, lineSpacing = 360) {
|
| 124 |
+
if (!text) return [];
|
| 125 |
+
|
| 126 |
+
return text.split('\n\n')
|
| 127 |
+
.filter(p => p.trim())
|
| 128 |
+
.map(para => new Paragraph({
|
| 129 |
+
children: [new TextRun({
|
| 130 |
+
text: para.trim(),
|
| 131 |
+
size: fontSize
|
| 132 |
+
})],
|
| 133 |
+
spacing: {
|
| 134 |
+
before: 120,
|
| 135 |
+
after: 120,
|
| 136 |
+
line: lineSpacing
|
| 137 |
+
},
|
| 138 |
+
alignment: AlignmentType.JUSTIFIED
|
| 139 |
+
}));
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
/**
|
| 143 |
+
* Format date in academic style
|
| 144 |
+
*/
|
| 145 |
+
function formatDate(dateString) {
|
| 146 |
+
const date = new Date(dateString);
|
| 147 |
+
const options = { day: 'numeric', month: 'long', year: 'numeric' };
|
| 148 |
+
return date.toLocaleDateString('en-GB', options);
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
/**
|
| 152 |
+
* Generate the complete academic report
|
| 153 |
+
*/
|
| 154 |
+
function generateAcademicReport(config, content = sampleContent) {
|
| 155 |
+
const cfg = { ...defaultConfig, ...config };
|
| 156 |
+
const fontSize = parseInt(cfg.fontSize) * 2; // Convert to half-points
|
| 157 |
+
const lineSpacing = Math.round(parseFloat(cfg.lineSpacing) * 240); // Convert to twips
|
| 158 |
+
|
| 159 |
+
const doc = new Document({
|
| 160 |
+
styles: {
|
| 161 |
+
default: {
|
| 162 |
+
document: {
|
| 163 |
+
run: {
|
| 164 |
+
font: cfg.fontFamily,
|
| 165 |
+
size: fontSize
|
| 166 |
+
},
|
| 167 |
+
paragraph: {
|
| 168 |
+
spacing: {
|
| 169 |
+
line: lineSpacing
|
| 170 |
+
}
|
| 171 |
+
}
|
| 172 |
+
}
|
| 173 |
+
},
|
| 174 |
+
paragraphStyles: [
|
| 175 |
+
{
|
| 176 |
+
id: "Heading1",
|
| 177 |
+
name: "Heading 1",
|
| 178 |
+
basedOn: "Normal",
|
| 179 |
+
next: "Normal",
|
| 180 |
+
quickFormat: true,
|
| 181 |
+
run: {
|
| 182 |
+
size: 32,
|
| 183 |
+
bold: true,
|
| 184 |
+
font: cfg.fontFamily,
|
| 185 |
+
color: "1F4788"
|
| 186 |
+
},
|
| 187 |
+
paragraph: {
|
| 188 |
+
spacing: { before: 480, after: 240, line: lineSpacing },
|
| 189 |
+
outlineLevel: 0,
|
| 190 |
+
border: {
|
| 191 |
+
bottom: {
|
| 192 |
+
color: "1F4788",
|
| 193 |
+
space: 1,
|
| 194 |
+
style: BorderStyle.SINGLE,
|
| 195 |
+
size: 6
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
}
|
| 199 |
+
},
|
| 200 |
+
{
|
| 201 |
+
id: "Heading2",
|
| 202 |
+
name: "Heading 2",
|
| 203 |
+
basedOn: "Normal",
|
| 204 |
+
next: "Normal",
|
| 205 |
+
quickFormat: true,
|
| 206 |
+
run: {
|
| 207 |
+
size: 28,
|
| 208 |
+
bold: true,
|
| 209 |
+
font: cfg.fontFamily,
|
| 210 |
+
color: "2E5C8A"
|
| 211 |
+
},
|
| 212 |
+
paragraph: {
|
| 213 |
+
spacing: { before: 360, after: 180, line: lineSpacing },
|
| 214 |
+
outlineLevel: 1
|
| 215 |
+
}
|
| 216 |
+
},
|
| 217 |
+
{
|
| 218 |
+
id: "Heading3",
|
| 219 |
+
name: "Heading 3",
|
| 220 |
+
basedOn: "Normal",
|
| 221 |
+
next: "Normal",
|
| 222 |
+
quickFormat: true,
|
| 223 |
+
run: {
|
| 224 |
+
size: 26,
|
| 225 |
+
bold: true,
|
| 226 |
+
font: cfg.fontFamily,
|
| 227 |
+
color: "4472C4"
|
| 228 |
+
},
|
| 229 |
+
paragraph: {
|
| 230 |
+
spacing: { before: 240, after: 120, line: lineSpacing },
|
| 231 |
+
outlineLevel: 2
|
| 232 |
+
}
|
| 233 |
+
}
|
| 234 |
+
]
|
| 235 |
+
},
|
| 236 |
+
|
| 237 |
+
numbering: {
|
| 238 |
+
config: [
|
| 239 |
+
{
|
| 240 |
+
reference: "references-numbering",
|
| 241 |
+
levels: [
|
| 242 |
+
{
|
| 243 |
+
level: 0,
|
| 244 |
+
format: LevelFormat.DECIMAL,
|
| 245 |
+
text: "[%1]",
|
| 246 |
+
alignment: AlignmentType.LEFT,
|
| 247 |
+
style: {
|
| 248 |
+
paragraph: {
|
| 249 |
+
indent: { left: 720, hanging: 360 }
|
| 250 |
+
}
|
| 251 |
+
}
|
| 252 |
+
}
|
| 253 |
+
]
|
| 254 |
+
}
|
| 255 |
+
]
|
| 256 |
+
},
|
| 257 |
+
|
| 258 |
+
sections: [
|
| 259 |
+
// ====== COVER PAGE SECTION ======
|
| 260 |
+
{
|
| 261 |
+
properties: {
|
| 262 |
+
page: {
|
| 263 |
+
size: { width: 12240, height: 15840 }, // US Letter
|
| 264 |
+
margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 }
|
| 265 |
+
}
|
| 266 |
+
},
|
| 267 |
+
children: [
|
| 268 |
+
// University Logo Space (optional)
|
| 269 |
+
new Paragraph({
|
| 270 |
+
spacing: { before: 480, after: 240 }
|
| 271 |
+
}),
|
| 272 |
+
|
| 273 |
+
// University Name
|
| 274 |
+
new Paragraph({
|
| 275 |
+
children: [
|
| 276 |
+
new TextRun({
|
| 277 |
+
text: cfg.university.toUpperCase(),
|
| 278 |
+
bold: true,
|
| 279 |
+
size: 36,
|
| 280 |
+
font: cfg.fontFamily,
|
| 281 |
+
color: "1F4788"
|
| 282 |
+
})
|
| 283 |
+
],
|
| 284 |
+
alignment: AlignmentType.CENTER,
|
| 285 |
+
spacing: { before: 960, after: 120 }
|
| 286 |
+
}),
|
| 287 |
+
|
| 288 |
+
// Department
|
| 289 |
+
new Paragraph({
|
| 290 |
+
children: [
|
| 291 |
+
new TextRun({
|
| 292 |
+
text: `Department of ${cfg.department}`,
|
| 293 |
+
bold: true,
|
| 294 |
+
size: 30,
|
| 295 |
+
font: cfg.fontFamily,
|
| 296 |
+
color: "2E5C8A"
|
| 297 |
+
})
|
| 298 |
+
],
|
| 299 |
+
alignment: AlignmentType.CENTER,
|
| 300 |
+
spacing: { after: 720 }
|
| 301 |
+
}),
|
| 302 |
+
|
| 303 |
+
// Decorative Top Border
|
| 304 |
+
new Paragraph({
|
| 305 |
+
border: {
|
| 306 |
+
top: {
|
| 307 |
+
color: "1F4788",
|
| 308 |
+
space: 1,
|
| 309 |
+
style: BorderStyle.DOUBLE,
|
| 310 |
+
size: 12
|
| 311 |
+
}
|
| 312 |
+
},
|
| 313 |
+
spacing: { before: 360, after: 360 }
|
| 314 |
+
}),
|
| 315 |
+
|
| 316 |
+
// Report Type Badge
|
| 317 |
+
new Paragraph({
|
| 318 |
+
children: [
|
| 319 |
+
new TextRun({
|
| 320 |
+
text: cfg.reportType.toUpperCase(),
|
| 321 |
+
bold: true,
|
| 322 |
+
size: 24,
|
| 323 |
+
font: cfg.fontFamily,
|
| 324 |
+
color: "FFFFFF"
|
| 325 |
+
})
|
| 326 |
+
],
|
| 327 |
+
alignment: AlignmentType.CENTER,
|
| 328 |
+
spacing: { before: 480, after: 240 },
|
| 329 |
+
shading: {
|
| 330 |
+
type: ShadingType.CLEAR,
|
| 331 |
+
fill: "4472C4"
|
| 332 |
+
},
|
| 333 |
+
border: {
|
| 334 |
+
top: { color: "4472C4", size: 6, style: BorderStyle.SINGLE },
|
| 335 |
+
bottom: { color: "4472C4", size: 6, style: BorderStyle.SINGLE },
|
| 336 |
+
left: { color: "4472C4", size: 6, style: BorderStyle.SINGLE },
|
| 337 |
+
right: { color: "4472C4", size: 6, style: BorderStyle.SINGLE }
|
| 338 |
+
}
|
| 339 |
+
}),
|
| 340 |
+
|
| 341 |
+
// Main Report Title
|
| 342 |
+
new Paragraph({
|
| 343 |
+
children: [
|
| 344 |
+
new TextRun({
|
| 345 |
+
text: cfg.reportTitle,
|
| 346 |
+
bold: true,
|
| 347 |
+
size: 40,
|
| 348 |
+
font: cfg.fontFamily,
|
| 349 |
+
color: "1F4788"
|
| 350 |
+
})
|
| 351 |
+
],
|
| 352 |
+
alignment: AlignmentType.CENTER,
|
| 353 |
+
spacing: { before: 480, after: 240 }
|
| 354 |
+
}),
|
| 355 |
+
|
| 356 |
+
// Topic/Subtitle (if different)
|
| 357 |
+
...(cfg.topic && cfg.topic !== cfg.reportTitle ? [
|
| 358 |
+
new Paragraph({
|
| 359 |
+
children: [
|
| 360 |
+
new TextRun({
|
| 361 |
+
text: cfg.topic,
|
| 362 |
+
size: 28,
|
| 363 |
+
font: cfg.fontFamily,
|
| 364 |
+
italics: true,
|
| 365 |
+
color: "2E5C8A"
|
| 366 |
+
})
|
| 367 |
+
],
|
| 368 |
+
alignment: AlignmentType.CENTER,
|
| 369 |
+
spacing: { after: 720 }
|
| 370 |
+
})
|
| 371 |
+
] : [
|
| 372 |
+
new Paragraph({
|
| 373 |
+
spacing: { after: 720 }
|
| 374 |
+
})
|
| 375 |
+
]),
|
| 376 |
+
|
| 377 |
+
// Decorative Middle Border
|
| 378 |
+
new Paragraph({
|
| 379 |
+
border: {
|
| 380 |
+
bottom: {
|
| 381 |
+
color: "1F4788",
|
| 382 |
+
space: 1,
|
| 383 |
+
style: BorderStyle.DOUBLE,
|
| 384 |
+
size: 12
|
| 385 |
+
}
|
| 386 |
+
},
|
| 387 |
+
spacing: { before: 360, after: 720 }
|
| 388 |
+
}),
|
| 389 |
+
|
| 390 |
+
// Course Information Section
|
| 391 |
+
new Paragraph({
|
| 392 |
+
children: [
|
| 393 |
+
new TextRun({
|
| 394 |
+
text: "Course Information",
|
| 395 |
+
bold: true,
|
| 396 |
+
size: 26,
|
| 397 |
+
font: cfg.fontFamily,
|
| 398 |
+
underline: { type: UnderlineType.SINGLE }
|
| 399 |
+
})
|
| 400 |
+
],
|
| 401 |
+
alignment: AlignmentType.CENTER,
|
| 402 |
+
spacing: { before: 240, after: 240 }
|
| 403 |
+
}),
|
| 404 |
+
|
| 405 |
+
new Paragraph({
|
| 406 |
+
children: [
|
| 407 |
+
new TextRun({
|
| 408 |
+
text: `${cfg.courseTitle} (${cfg.courseCode})`,
|
| 409 |
+
size: 24,
|
| 410 |
+
font: cfg.fontFamily,
|
| 411 |
+
bold: true
|
| 412 |
+
})
|
| 413 |
+
],
|
| 414 |
+
alignment: AlignmentType.CENTER,
|
| 415 |
+
spacing: { after: 480 }
|
| 416 |
+
}),
|
| 417 |
+
|
| 418 |
+
// Instructor Information
|
| 419 |
+
new Paragraph({
|
| 420 |
+
children: [
|
| 421 |
+
new TextRun({
|
| 422 |
+
text: "Submitted To:",
|
| 423 |
+
bold: true,
|
| 424 |
+
size: 24,
|
| 425 |
+
font: cfg.fontFamily
|
| 426 |
+
}),
|
| 427 |
+
new TextRun({
|
| 428 |
+
text: "\n" + cfg.teacherName,
|
| 429 |
+
size: 24,
|
| 430 |
+
font: cfg.fontFamily
|
| 431 |
+
}),
|
| 432 |
+
...(cfg.teacherDesignation ? [
|
| 433 |
+
new TextRun({
|
| 434 |
+
text: `\n${cfg.teacherDesignation}`,
|
| 435 |
+
size: 22,
|
| 436 |
+
font: cfg.fontFamily,
|
| 437 |
+
italics: true
|
| 438 |
+
})
|
| 439 |
+
] : [])
|
| 440 |
+
],
|
| 441 |
+
alignment: AlignmentType.CENTER,
|
| 442 |
+
spacing: { before: 360, after: 480 }
|
| 443 |
+
}),
|
| 444 |
+
|
| 445 |
+
// Student Information
|
| 446 |
+
new Paragraph({
|
| 447 |
+
children: [
|
| 448 |
+
new TextRun({
|
| 449 |
+
text: "Submitted By:",
|
| 450 |
+
bold: true,
|
| 451 |
+
size: 24,
|
| 452 |
+
font: cfg.fontFamily
|
| 453 |
+
}),
|
| 454 |
+
new TextRun({
|
| 455 |
+
text: "\n" + cfg.studentName,
|
| 456 |
+
size: 26,
|
| 457 |
+
font: cfg.fontFamily,
|
| 458 |
+
bold: true,
|
| 459 |
+
color: "1F4788"
|
| 460 |
+
}),
|
| 461 |
+
new TextRun({
|
| 462 |
+
text: `\nStudent ID: ${cfg.studentId}`,
|
| 463 |
+
size: 22,
|
| 464 |
+
font: cfg.fontFamily
|
| 465 |
+
}),
|
| 466 |
+
new TextRun({
|
| 467 |
+
text: `\n${cfg.department}`,
|
| 468 |
+
size: 22,
|
| 469 |
+
font: cfg.fontFamily,
|
| 470 |
+
italics: true
|
| 471 |
+
})
|
| 472 |
+
],
|
| 473 |
+
alignment: AlignmentType.CENTER,
|
| 474 |
+
spacing: { after: 480 }
|
| 475 |
+
}),
|
| 476 |
+
|
| 477 |
+
// Submission Date
|
| 478 |
+
new Paragraph({
|
| 479 |
+
children: [
|
| 480 |
+
new TextRun({
|
| 481 |
+
text: "Date of Submission:",
|
| 482 |
+
bold: true,
|
| 483 |
+
size: 22,
|
| 484 |
+
font: cfg.fontFamily
|
| 485 |
+
}),
|
| 486 |
+
new TextRun({
|
| 487 |
+
text: "\n" + formatDate(cfg.submissionDate),
|
| 488 |
+
size: 24,
|
| 489 |
+
font: cfg.fontFamily,
|
| 490 |
+
bold: true
|
| 491 |
+
})
|
| 492 |
+
],
|
| 493 |
+
alignment: AlignmentType.CENTER,
|
| 494 |
+
spacing: { before: 480 }
|
| 495 |
+
}),
|
| 496 |
+
|
| 497 |
+
// Decorative Bottom Border
|
| 498 |
+
new Paragraph({
|
| 499 |
+
border: {
|
| 500 |
+
bottom: {
|
| 501 |
+
color: "1F4788",
|
| 502 |
+
space: 1,
|
| 503 |
+
style: BorderStyle.TRIPLE,
|
| 504 |
+
size: 12
|
| 505 |
+
}
|
| 506 |
+
},
|
| 507 |
+
spacing: { before: 720 }
|
| 508 |
+
}),
|
| 509 |
+
|
| 510 |
+
// Page Break
|
| 511 |
+
new Paragraph({
|
| 512 |
+
children: [new PageBreak()]
|
| 513 |
+
})
|
| 514 |
+
]
|
| 515 |
+
},
|
| 516 |
+
|
| 517 |
+
// ====== MAIN CONTENT SECTION ======
|
| 518 |
+
{
|
| 519 |
+
properties: {
|
| 520 |
+
page: {
|
| 521 |
+
size: { width: 12240, height: 15840 },
|
| 522 |
+
margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 }
|
| 523 |
+
}
|
| 524 |
+
},
|
| 525 |
+
footers: cfg.pageNumbers ? {
|
| 526 |
+
default: new Footer({
|
| 527 |
+
children: [
|
| 528 |
+
new Paragraph({
|
| 529 |
+
alignment: AlignmentType.CENTER,
|
| 530 |
+
children: [
|
| 531 |
+
new TextRun({
|
| 532 |
+
text: "Page ",
|
| 533 |
+
size: fontSize
|
| 534 |
+
}),
|
| 535 |
+
new TextRun({
|
| 536 |
+
children: [PageNumber.CURRENT],
|
| 537 |
+
size: fontSize
|
| 538 |
+
}),
|
| 539 |
+
new TextRun({
|
| 540 |
+
text: " of ",
|
| 541 |
+
size: fontSize
|
| 542 |
+
}),
|
| 543 |
+
new TextRun({
|
| 544 |
+
children: [PageNumber.TOTAL_PAGES],
|
| 545 |
+
size: fontSize
|
| 546 |
+
})
|
| 547 |
+
]
|
| 548 |
+
})
|
| 549 |
+
]
|
| 550 |
+
})
|
| 551 |
+
} : undefined,
|
| 552 |
+
children: [
|
| 553 |
+
// ====== TABLE OF CONTENTS ======
|
| 554 |
+
...(cfg.includeTOC ? [
|
| 555 |
+
new Paragraph({
|
| 556 |
+
heading: HeadingLevel.HEADING_1,
|
| 557 |
+
children: [new TextRun("Table of Contents")],
|
| 558 |
+
pageBreakBefore: false
|
| 559 |
+
}),
|
| 560 |
+
new TableOfContents("Table of Contents", {
|
| 561 |
+
hyperlink: true,
|
| 562 |
+
headingStyleRange: "1-3",
|
| 563 |
+
stylesWithLevels: [
|
| 564 |
+
{ heading: HeadingLevel.HEADING_1, level: 0 },
|
| 565 |
+
{ heading: HeadingLevel.HEADING_2, level: 1 },
|
| 566 |
+
{ heading: HeadingLevel.HEADING_3, level: 2 }
|
| 567 |
+
]
|
| 568 |
+
}),
|
| 569 |
+
new Paragraph({
|
| 570 |
+
children: [new PageBreak()]
|
| 571 |
+
})
|
| 572 |
+
] : []),
|
| 573 |
+
|
| 574 |
+
// ====== ABSTRACT ======
|
| 575 |
+
...(cfg.includeAbstract && content.abstract ? [
|
| 576 |
+
new Paragraph({
|
| 577 |
+
heading: HeadingLevel.HEADING_1,
|
| 578 |
+
children: [new TextRun("Abstract")]
|
| 579 |
+
}),
|
| 580 |
+
new Paragraph({
|
| 581 |
+
children: [new TextRun({
|
| 582 |
+
text: content.abstract,
|
| 583 |
+
italics: true,
|
| 584 |
+
size: fontSize
|
| 585 |
+
})],
|
| 586 |
+
alignment: AlignmentType.JUSTIFIED,
|
| 587 |
+
spacing: { before: 240, after: 480, line: lineSpacing }
|
| 588 |
+
}),
|
| 589 |
+
new Paragraph({
|
| 590 |
+
children: [new PageBreak()]
|
| 591 |
+
})
|
| 592 |
+
] : []),
|
| 593 |
+
|
| 594 |
+
// ====== INTRODUCTION ======
|
| 595 |
+
new Paragraph({
|
| 596 |
+
heading: HeadingLevel.HEADING_1,
|
| 597 |
+
children: [new TextRun("1. Introduction")]
|
| 598 |
+
}),
|
| 599 |
+
...createParagraphs(content.introduction, fontSize, lineSpacing),
|
| 600 |
+
new Paragraph({ spacing: { after: 480 } }),
|
| 601 |
+
|
| 602 |
+
// ====== LITERATURE REVIEW ======
|
| 603 |
+
new Paragraph({
|
| 604 |
+
heading: HeadingLevel.HEADING_1,
|
| 605 |
+
children: [new TextRun("2. Literature Review")]
|
| 606 |
+
}),
|
| 607 |
+
...createParagraphs(content.literatureReview, fontSize, lineSpacing),
|
| 608 |
+
new Paragraph({ spacing: { after: 480 } }),
|
| 609 |
+
|
| 610 |
+
// ====== METHODOLOGY ======
|
| 611 |
+
new Paragraph({
|
| 612 |
+
heading: HeadingLevel.HEADING_1,
|
| 613 |
+
children: [new TextRun("3. Methodology")]
|
| 614 |
+
}),
|
| 615 |
+
...createParagraphs(content.methodology, fontSize, lineSpacing),
|
| 616 |
+
new Paragraph({
|
| 617 |
+
children: [new PageBreak()]
|
| 618 |
+
}),
|
| 619 |
+
|
| 620 |
+
// ====== RESULTS ======
|
| 621 |
+
new Paragraph({
|
| 622 |
+
heading: HeadingLevel.HEADING_1,
|
| 623 |
+
children: [new TextRun("4. Results and Findings")]
|
| 624 |
+
}),
|
| 625 |
+
...createParagraphs(content.results, fontSize, lineSpacing),
|
| 626 |
+
new Paragraph({ spacing: { after: 480 } }),
|
| 627 |
+
|
| 628 |
+
// ====== DISCUSSION ======
|
| 629 |
+
new Paragraph({
|
| 630 |
+
heading: HeadingLevel.HEADING_1,
|
| 631 |
+
children: [new TextRun("5. Discussion")]
|
| 632 |
+
}),
|
| 633 |
+
...createParagraphs(content.discussion, fontSize, lineSpacing),
|
| 634 |
+
new Paragraph({ spacing: { after: 480 } }),
|
| 635 |
+
|
| 636 |
+
// ====== CONCLUSION ======
|
| 637 |
+
new Paragraph({
|
| 638 |
+
heading: HeadingLevel.HEADING_1,
|
| 639 |
+
children: [new TextRun("6. Conclusion")]
|
| 640 |
+
}),
|
| 641 |
+
...createParagraphs(content.conclusion, fontSize, lineSpacing),
|
| 642 |
+
|
| 643 |
+
// ====== REFERENCES ======
|
| 644 |
+
...(cfg.includeReferences && content.references && content.references.length > 0 ? [
|
| 645 |
+
new Paragraph({
|
| 646 |
+
children: [new PageBreak()]
|
| 647 |
+
}),
|
| 648 |
+
new Paragraph({
|
| 649 |
+
heading: HeadingLevel.HEADING_1,
|
| 650 |
+
children: [new TextRun("References")]
|
| 651 |
+
}),
|
| 652 |
+
...content.references.map((ref, idx) =>
|
| 653 |
+
new Paragraph({
|
| 654 |
+
numbering: {
|
| 655 |
+
reference: "references-numbering",
|
| 656 |
+
level: 0
|
| 657 |
+
},
|
| 658 |
+
children: [new TextRun({
|
| 659 |
+
text: ref,
|
| 660 |
+
size: fontSize
|
| 661 |
+
})],
|
| 662 |
+
spacing: { before: 120, after: 120, line: lineSpacing },
|
| 663 |
+
alignment: AlignmentType.LEFT
|
| 664 |
+
})
|
| 665 |
+
)
|
| 666 |
+
] : [])
|
| 667 |
+
]
|
| 668 |
+
}
|
| 669 |
+
]
|
| 670 |
+
});
|
| 671 |
+
|
| 672 |
+
return doc;
|
| 673 |
+
}
|
| 674 |
+
|
| 675 |
+
/**
|
| 676 |
+
* Main execution
|
| 677 |
+
*/
|
| 678 |
+
async function main() {
|
| 679 |
+
try {
|
| 680 |
+
// Check for config file argument
|
| 681 |
+
let config = defaultConfig;
|
| 682 |
+
|
| 683 |
+
const configArgIndex = process.argv.indexOf('--config');
|
| 684 |
+
if (configArgIndex !== -1 && process.argv[configArgIndex + 1]) {
|
| 685 |
+
const configPath = process.argv[configArgIndex + 1];
|
| 686 |
+
const configData = fs.readFileSync(configPath, 'utf8');
|
| 687 |
+
config = { ...defaultConfig, ...JSON.parse(configData) };
|
| 688 |
+
}
|
| 689 |
+
|
| 690 |
+
console.log('🎓 Smart Academic Report Generator');
|
| 691 |
+
console.log('━'.repeat(50));
|
| 692 |
+
console.log(`📚 Generating report for: ${config.studentName}`);
|
| 693 |
+
console.log(`📝 Title: ${config.reportTitle}`);
|
| 694 |
+
console.log(`🏛️ University: ${config.university}`);
|
| 695 |
+
console.log('━'.repeat(50));
|
| 696 |
+
|
| 697 |
+
// Generate document
|
| 698 |
+
const doc = generateAcademicReport(config);
|
| 699 |
+
|
| 700 |
+
// Output path
|
| 701 |
+
const outputPath = path.join('/mnt/user-data/outputs', 'academic-report.docx');
|
| 702 |
+
|
| 703 |
+
// Ensure output directory exists
|
| 704 |
+
const outputDir = path.dirname(outputPath);
|
| 705 |
+
if (!fs.existsSync(outputDir)) {
|
| 706 |
+
fs.mkdirSync(outputDir, { recursive: true });
|
| 707 |
+
}
|
| 708 |
+
|
| 709 |
+
// Generate buffer and save
|
| 710 |
+
const buffer = await Packer.toBuffer(doc);
|
| 711 |
+
fs.writeFileSync(outputPath, buffer);
|
| 712 |
+
|
| 713 |
+
console.log('✅ Document generated successfully!');
|
| 714 |
+
console.log(`📄 Saved to: ${outputPath}`);
|
| 715 |
+
console.log('━'.repeat(50));
|
| 716 |
+
console.log('✨ Features included:');
|
| 717 |
+
console.log(' • Professional Cover Page');
|
| 718 |
+
if (config.includeTOC) console.log(' • Table of Contents');
|
| 719 |
+
if (config.includeAbstract) console.log(' • Abstract');
|
| 720 |
+
console.log(' • Complete Report Structure');
|
| 721 |
+
if (config.includeReferences) console.log(' • APA Style References');
|
| 722 |
+
if (config.pageNumbers) console.log(' • Page Numbers');
|
| 723 |
+
console.log('━'.repeat(50));
|
| 724 |
+
|
| 725 |
+
} catch (error) {
|
| 726 |
+
console.error('❌ Error generating document:', error);
|
| 727 |
+
process.exit(1);
|
| 728 |
+
}
|
| 729 |
+
}
|
| 730 |
+
|
| 731 |
+
// Run if called directly
|
| 732 |
+
if (require.main === module) {
|
| 733 |
+
main();
|
| 734 |
+
}
|
| 735 |
+
|
| 736 |
+
// Export for use as module
|
| 737 |
+
module.exports = { generateAcademicReport, defaultConfig, sampleContent };
|
index.html
ADDED
|
@@ -0,0 +1,564 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>🎓 Smart Academic Report Generator</title>
|
| 7 |
+
<style>
|
| 8 |
+
* {
|
| 9 |
+
margin: 0;
|
| 10 |
+
padding: 0;
|
| 11 |
+
box-sizing: border-box;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
body {
|
| 15 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 16 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 17 |
+
min-height: 100vh;
|
| 18 |
+
padding: 20px;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
.container {
|
| 22 |
+
max-width: 1200px;
|
| 23 |
+
margin: 0 auto;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
.header {
|
| 27 |
+
text-align: center;
|
| 28 |
+
margin-bottom: 40px;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
.header-badge {
|
| 32 |
+
display: inline-flex;
|
| 33 |
+
align-items: center;
|
| 34 |
+
gap: 15px;
|
| 35 |
+
background: rgba(255, 255, 255, 0.1);
|
| 36 |
+
backdrop-filter: blur(10px);
|
| 37 |
+
padding: 15px 30px;
|
| 38 |
+
border-radius: 50px;
|
| 39 |
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
| 40 |
+
margin-bottom: 20px;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
.header h1 {
|
| 44 |
+
font-size: 2.5em;
|
| 45 |
+
color: white;
|
| 46 |
+
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
|
| 47 |
+
margin: 0;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
.header p {
|
| 51 |
+
color: rgba(255, 255, 255, 0.9);
|
| 52 |
+
font-size: 1.2em;
|
| 53 |
+
font-weight: 500;
|
| 54 |
+
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
.main-card {
|
| 58 |
+
background: white;
|
| 59 |
+
border-radius: 20px;
|
| 60 |
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
| 61 |
+
overflow: hidden;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
.form-content {
|
| 65 |
+
padding: 40px;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
.section {
|
| 69 |
+
padding: 30px;
|
| 70 |
+
border-radius: 15px;
|
| 71 |
+
margin-bottom: 30px;
|
| 72 |
+
border: 2px solid;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
.section.student {
|
| 76 |
+
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
| 77 |
+
border-color: #667eea;
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
.section.course {
|
| 81 |
+
background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
|
| 82 |
+
border-color: #f6ad55;
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
.section.report {
|
| 86 |
+
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
| 87 |
+
border-color: #48bb78;
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
.section.formatting {
|
| 91 |
+
background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
|
| 92 |
+
border-color: #e53e3e;
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
.section-header {
|
| 96 |
+
display: flex;
|
| 97 |
+
align-items: center;
|
| 98 |
+
gap: 10px;
|
| 99 |
+
margin-bottom: 20px;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
.section-header h2 {
|
| 103 |
+
font-size: 1.5em;
|
| 104 |
+
color: #2d3748;
|
| 105 |
+
font-weight: 700;
|
| 106 |
+
margin: 0;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
.form-grid {
|
| 110 |
+
display: grid;
|
| 111 |
+
gap: 20px;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.grid-2 {
|
| 115 |
+
grid-template-columns: repeat(2, 1fr);
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
.grid-3 {
|
| 119 |
+
grid-template-columns: repeat(3, 1fr);
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
.grid-4 {
|
| 123 |
+
grid-template-columns: repeat(4, 1fr);
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
.form-group {
|
| 127 |
+
display: flex;
|
| 128 |
+
flex-direction: column;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
label {
|
| 132 |
+
display: block;
|
| 133 |
+
margin-bottom: 8px;
|
| 134 |
+
font-size: 0.95em;
|
| 135 |
+
font-weight: 700;
|
| 136 |
+
color: #2d3748;
|
| 137 |
+
text-transform: uppercase;
|
| 138 |
+
letter-spacing: 0.5px;
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
input, select, textarea {
|
| 142 |
+
width: 100%;
|
| 143 |
+
padding: 12px 15px;
|
| 144 |
+
font-size: 1em;
|
| 145 |
+
border: 2px solid rgba(0, 0, 0, 0.1);
|
| 146 |
+
border-radius: 8px;
|
| 147 |
+
transition: all 0.3s;
|
| 148 |
+
background: rgba(255, 255, 255, 0.9);
|
| 149 |
+
font-family: inherit;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
input:focus, select:focus, textarea:focus {
|
| 153 |
+
outline: none;
|
| 154 |
+
border-color: #667eea;
|
| 155 |
+
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
textarea {
|
| 159 |
+
min-height: 80px;
|
| 160 |
+
resize: vertical;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
.checkbox-grid {
|
| 164 |
+
display: grid;
|
| 165 |
+
grid-template-columns: repeat(4, 1fr);
|
| 166 |
+
gap: 15px;
|
| 167 |
+
margin-top: 20px;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
.checkbox-label {
|
| 171 |
+
display: flex;
|
| 172 |
+
align-items: center;
|
| 173 |
+
gap: 10px;
|
| 174 |
+
padding: 12px;
|
| 175 |
+
background: rgba(255, 255, 255, 0.6);
|
| 176 |
+
border-radius: 8px;
|
| 177 |
+
cursor: pointer;
|
| 178 |
+
transition: all 0.3s;
|
| 179 |
+
border: 2px solid transparent;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
.checkbox-label:hover {
|
| 183 |
+
border-color: #e53e3e;
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
.checkbox-label input {
|
| 187 |
+
width: 18px;
|
| 188 |
+
height: 18px;
|
| 189 |
+
cursor: pointer;
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
.checkbox-label span {
|
| 193 |
+
font-size: 0.95em;
|
| 194 |
+
font-weight: 600;
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
.generate-btn {
|
| 198 |
+
width: 100%;
|
| 199 |
+
padding: 20px 40px;
|
| 200 |
+
font-size: 1.3em;
|
| 201 |
+
font-weight: 700;
|
| 202 |
+
color: white;
|
| 203 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 204 |
+
border: none;
|
| 205 |
+
border-radius: 15px;
|
| 206 |
+
cursor: pointer;
|
| 207 |
+
display: flex;
|
| 208 |
+
align-items: center;
|
| 209 |
+
justify-content: center;
|
| 210 |
+
gap: 15px;
|
| 211 |
+
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4);
|
| 212 |
+
transition: all 0.3s;
|
| 213 |
+
margin-top: 20px;
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
.generate-btn:hover {
|
| 217 |
+
transform: scale(1.02);
|
| 218 |
+
box-shadow: 0 15px 40px rgba(102, 126, 234, 0.6);
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
.generate-btn:disabled {
|
| 222 |
+
background: linear-gradient(135deg, #a0a0a0 0%, #808080 100%);
|
| 223 |
+
cursor: not-allowed;
|
| 224 |
+
transform: scale(0.98);
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
.alert {
|
| 228 |
+
padding: 20px;
|
| 229 |
+
border-radius: 12px;
|
| 230 |
+
display: flex;
|
| 231 |
+
align-items: center;
|
| 232 |
+
gap: 15px;
|
| 233 |
+
margin-top: 20px;
|
| 234 |
+
border: 2px solid;
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
.alert.success {
|
| 238 |
+
background: linear-gradient(135deg, #9ae6b4 0%, #c6f6d5 100%);
|
| 239 |
+
border-color: #48bb78;
|
| 240 |
+
color: #22543d;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
.alert.error {
|
| 244 |
+
background: linear-gradient(135deg, #fc8181 0%, #feb2b2 100%);
|
| 245 |
+
border-color: #e53e3e;
|
| 246 |
+
color: #742a2a;
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
.footer {
|
| 250 |
+
padding: 30px;
|
| 251 |
+
background: linear-gradient(135deg, #434343 0%, #000000 100%);
|
| 252 |
+
color: rgba(255, 255, 255, 0.8);
|
| 253 |
+
text-align: center;
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
.spinner {
|
| 257 |
+
animation: spin 1s linear infinite;
|
| 258 |
+
}
|
| 259 |
+
|
| 260 |
+
@keyframes spin {
|
| 261 |
+
from { transform: rotate(0deg); }
|
| 262 |
+
to { transform: rotate(360deg); }
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
@media (max-width: 768px) {
|
| 266 |
+
.grid-2, .grid-3, .grid-4, .checkbox-grid {
|
| 267 |
+
grid-template-columns: 1fr;
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
.header h1 {
|
| 271 |
+
font-size: 1.8em;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
.form-content {
|
| 275 |
+
padding: 20px;
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
.section {
|
| 279 |
+
padding: 20px;
|
| 280 |
+
}
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
.icon {
|
| 284 |
+
width: 24px;
|
| 285 |
+
height: 24px;
|
| 286 |
+
}
|
| 287 |
+
</style>
|
| 288 |
+
</head>
|
| 289 |
+
<body>
|
| 290 |
+
<div class="container">
|
| 291 |
+
<!-- Header -->
|
| 292 |
+
<div class="header">
|
| 293 |
+
<div class="header-badge">
|
| 294 |
+
<svg class="icon" fill="white" viewBox="0 0 24 24">
|
| 295 |
+
<path d="M12 3L1 9l4 2.18v6L12 21l7-3.82v-6l2-1.09V17h2V9L12 3zm6.82 6L12 12.72 5.18 9 12 5.28 18.82 9zM17 15.99l-5 2.73-5-2.73v-3.72L12 15l5-2.73v3.72z"/>
|
| 296 |
+
</svg>
|
| 297 |
+
<h1>Smart Academic Report Generator</h1>
|
| 298 |
+
</div>
|
| 299 |
+
<p>Professional PhD-Level Reports in Minutes ✨</p>
|
| 300 |
+
</div>
|
| 301 |
+
|
| 302 |
+
<!-- Main Card -->
|
| 303 |
+
<div class="main-card">
|
| 304 |
+
<form id="reportForm" class="form-content">
|
| 305 |
+
<!-- Student Information -->
|
| 306 |
+
<div class="section student">
|
| 307 |
+
<div class="section-header">
|
| 308 |
+
<svg class="icon" fill="#667eea" viewBox="0 0 24 24">
|
| 309 |
+
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
|
| 310 |
+
</svg>
|
| 311 |
+
<h2>Student Information</h2>
|
| 312 |
+
</div>
|
| 313 |
+
<div class="form-grid grid-2">
|
| 314 |
+
<div class="form-group">
|
| 315 |
+
<label>Full Name *</label>
|
| 316 |
+
<input type="text" id="studentName" required placeholder="e.g., Md. Rahman Ahmed">
|
| 317 |
+
</div>
|
| 318 |
+
<div class="form-group">
|
| 319 |
+
<label>Student ID *</label>
|
| 320 |
+
<input type="text" id="studentId" required placeholder="e.g., 2023-1-60-001">
|
| 321 |
+
</div>
|
| 322 |
+
<div class="form-group">
|
| 323 |
+
<label>Department *</label>
|
| 324 |
+
<input type="text" id="department" required placeholder="e.g., Computer Science & Engineering">
|
| 325 |
+
</div>
|
| 326 |
+
<div class="form-group">
|
| 327 |
+
<label>University *</label>
|
| 328 |
+
<input type="text" id="university" required placeholder="e.g., East West University">
|
| 329 |
+
</div>
|
| 330 |
+
</div>
|
| 331 |
+
</div>
|
| 332 |
+
|
| 333 |
+
<!-- Course Information -->
|
| 334 |
+
<div class="section course">
|
| 335 |
+
<div class="section-header">
|
| 336 |
+
<svg class="icon" fill="#f6ad55" viewBox="0 0 24 24">
|
| 337 |
+
<path d="M21 5c-1.11-.35-2.33-.5-3.5-.5-1.95 0-4.05.4-5.5 1.5-1.45-1.1-3.55-1.5-5.5-1.5S2.45 4.9 1 6v14.65c0 .25.25.5.5.5.1 0 .15-.05.25-.05C3.1 20.45 5.05 20 6.5 20c1.95 0 4.05.4 5.5 1.5 1.35-.85 3.8-1.5 5.5-1.5 1.65 0 3.35.3 4.75 1.05.1.05.15.05.25.05.25 0 .5-.25.5-.5V6c-.6-.45-1.25-.75-2-1zm0 13.5c-1.1-.35-2.3-.5-3.5-.5-1.7 0-4.15.65-5.5 1.5V8c1.35-.85 3.8-1.5 5.5-1.5 1.2 0 2.4.15 3.5.5v11.5z"/>
|
| 338 |
+
</svg>
|
| 339 |
+
<h2>Course Information</h2>
|
| 340 |
+
</div>
|
| 341 |
+
<div class="form-grid grid-2">
|
| 342 |
+
<div class="form-group">
|
| 343 |
+
<label>Course Title *</label>
|
| 344 |
+
<input type="text" id="courseTitle" required placeholder="e.g., Artificial Intelligence">
|
| 345 |
+
</div>
|
| 346 |
+
<div class="form-group">
|
| 347 |
+
<label>Course Code *</label>
|
| 348 |
+
<input type="text" id="courseCode" required placeholder="e.g., CSE 366">
|
| 349 |
+
</div>
|
| 350 |
+
<div class="form-group">
|
| 351 |
+
<label>Instructor Name *</label>
|
| 352 |
+
<input type="text" id="teacherName" required placeholder="e.g., Dr. Sarah Johnson">
|
| 353 |
+
</div>
|
| 354 |
+
<div class="form-group">
|
| 355 |
+
<label>Designation</label>
|
| 356 |
+
<input type="text" id="teacherDesignation" placeholder="e.g., Associate Professor">
|
| 357 |
+
</div>
|
| 358 |
+
</div>
|
| 359 |
+
</div>
|
| 360 |
+
|
| 361 |
+
<!-- Report Details -->
|
| 362 |
+
<div class="section report">
|
| 363 |
+
<div class="section-header">
|
| 364 |
+
<svg class="icon" fill="#48bb78" viewBox="0 0 24 24">
|
| 365 |
+
<path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/>
|
| 366 |
+
</svg>
|
| 367 |
+
<h2>Report Details</h2>
|
| 368 |
+
</div>
|
| 369 |
+
<div class="form-grid">
|
| 370 |
+
<div class="form-grid grid-2">
|
| 371 |
+
<div class="form-group">
|
| 372 |
+
<label>Report Type *</label>
|
| 373 |
+
<select id="reportType">
|
| 374 |
+
<option value="assignment">Assignment</option>
|
| 375 |
+
<option value="project">Project Report</option>
|
| 376 |
+
<option value="thesis">Thesis</option>
|
| 377 |
+
<option value="research">Research Paper</option>
|
| 378 |
+
<option value="case-study">Case Study</option>
|
| 379 |
+
<option value="lab-report">Lab Report</option>
|
| 380 |
+
</select>
|
| 381 |
+
</div>
|
| 382 |
+
<div class="form-group">
|
| 383 |
+
<label>Submission Date *</label>
|
| 384 |
+
<input type="date" id="submissionDate" required>
|
| 385 |
+
</div>
|
| 386 |
+
</div>
|
| 387 |
+
<div class="form-group">
|
| 388 |
+
<label>Report Title *</label>
|
| 389 |
+
<input type="text" id="reportTitle" required placeholder="e.g., Deep Learning Applications in Medical Imaging">
|
| 390 |
+
</div>
|
| 391 |
+
<div class="form-group">
|
| 392 |
+
<label>Topic/Subject Area *</label>
|
| 393 |
+
<textarea id="topic" required placeholder="e.g., Analysis of convolutional neural networks for detecting lung cancer from CT scans"></textarea>
|
| 394 |
+
</div>
|
| 395 |
+
</div>
|
| 396 |
+
</div>
|
| 397 |
+
|
| 398 |
+
<!-- Formatting Options -->
|
| 399 |
+
<div class="section formatting">
|
| 400 |
+
<div class="section-header">
|
| 401 |
+
<svg class="icon" fill="#e53e3e" viewBox="0 0 24 24">
|
| 402 |
+
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
| 403 |
+
</svg>
|
| 404 |
+
<h2>Document Settings</h2>
|
| 405 |
+
</div>
|
| 406 |
+
<div class="form-grid grid-3">
|
| 407 |
+
<div class="form-group">
|
| 408 |
+
<label>Font Family</label>
|
| 409 |
+
<select id="fontFamily">
|
| 410 |
+
<option value="Times New Roman">Times New Roman</option>
|
| 411 |
+
<option value="Arial">Arial</option>
|
| 412 |
+
<option value="Calibri">Calibri</option>
|
| 413 |
+
<option value="Georgia">Georgia</option>
|
| 414 |
+
</select>
|
| 415 |
+
</div>
|
| 416 |
+
<div class="form-group">
|
| 417 |
+
<label>Font Size</label>
|
| 418 |
+
<select id="fontSize">
|
| 419 |
+
<option value="11">11 pt</option>
|
| 420 |
+
<option value="12" selected>12 pt</option>
|
| 421 |
+
<option value="14">14 pt</option>
|
| 422 |
+
</select>
|
| 423 |
+
</div>
|
| 424 |
+
<div class="form-group">
|
| 425 |
+
<label>Line Spacing</label>
|
| 426 |
+
<select id="lineSpacing">
|
| 427 |
+
<option value="1.0">Single</option>
|
| 428 |
+
<option value="1.5" selected>1.5 Lines</option>
|
| 429 |
+
<option value="2.0">Double</option>
|
| 430 |
+
</select>
|
| 431 |
+
</div>
|
| 432 |
+
</div>
|
| 433 |
+
<div class="checkbox-grid">
|
| 434 |
+
<label class="checkbox-label">
|
| 435 |
+
<input type="checkbox" id="includeAbstract" checked>
|
| 436 |
+
<span>Include Abstract</span>
|
| 437 |
+
</label>
|
| 438 |
+
<label class="checkbox-label">
|
| 439 |
+
<input type="checkbox" id="includeTOC" checked>
|
| 440 |
+
<span>Table of Contents</span>
|
| 441 |
+
</label>
|
| 442 |
+
<label class="checkbox-label">
|
| 443 |
+
<input type="checkbox" id="includeReferences" checked>
|
| 444 |
+
<span>References</span>
|
| 445 |
+
</label>
|
| 446 |
+
<label class="checkbox-label">
|
| 447 |
+
<input type="checkbox" id="pageNumbers" checked>
|
| 448 |
+
<span>Page Numbers</span>
|
| 449 |
+
</label>
|
| 450 |
+
</div>
|
| 451 |
+
</div>
|
| 452 |
+
|
| 453 |
+
<!-- Generate Button -->
|
| 454 |
+
<button type="submit" class="generate-btn" id="generateBtn">
|
| 455 |
+
<svg class="icon" fill="white" viewBox="0 0 24 24">
|
| 456 |
+
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
|
| 457 |
+
</svg>
|
| 458 |
+
Generate Academic Report
|
| 459 |
+
</button>
|
| 460 |
+
|
| 461 |
+
<!-- Alerts -->
|
| 462 |
+
<div id="alertContainer"></div>
|
| 463 |
+
</form>
|
| 464 |
+
|
| 465 |
+
<!-- Footer -->
|
| 466 |
+
<div class="footer">
|
| 467 |
+
<p style="margin: 0 0 10px 0; font-size: 1.1em; font-weight: 600;">
|
| 468 |
+
🎓 Smart Academic Report Generator
|
| 469 |
+
</p>
|
| 470 |
+
<p style="margin: 0; font-size: 0.9em; opacity: 0.7;">
|
| 471 |
+
Professional PhD-Level Reports • Auto Cover Page • Table of Contents • APA References
|
| 472 |
+
</p>
|
| 473 |
+
</div>
|
| 474 |
+
</div>
|
| 475 |
+
</div>
|
| 476 |
+
|
| 477 |
+
<script>
|
| 478 |
+
// Set default date to today
|
| 479 |
+
document.getElementById('submissionDate').valueAsDate = new Date();
|
| 480 |
+
|
| 481 |
+
// Form submission handler
|
| 482 |
+
document.getElementById('reportForm').addEventListener('submit', async function(e) {
|
| 483 |
+
e.preventDefault();
|
| 484 |
+
|
| 485 |
+
const generateBtn = document.getElementById('generateBtn');
|
| 486 |
+
const alertContainer = document.getElementById('alertContainer');
|
| 487 |
+
|
| 488 |
+
// Disable button and show loading
|
| 489 |
+
generateBtn.disabled = true;
|
| 490 |
+
generateBtn.innerHTML = `
|
| 491 |
+
<svg class="icon spinner" fill="white" viewBox="0 0 24 24">
|
| 492 |
+
<path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/>
|
| 493 |
+
</svg>
|
| 494 |
+
Generating Your Professional Report...
|
| 495 |
+
`;
|
| 496 |
+
|
| 497 |
+
// Collect form data
|
| 498 |
+
const formData = {
|
| 499 |
+
studentName: document.getElementById('studentName').value,
|
| 500 |
+
studentId: document.getElementById('studentId').value,
|
| 501 |
+
department: document.getElementById('department').value,
|
| 502 |
+
university: document.getElementById('university').value,
|
| 503 |
+
courseTitle: document.getElementById('courseTitle').value,
|
| 504 |
+
courseCode: document.getElementById('courseCode').value,
|
| 505 |
+
teacherName: document.getElementById('teacherName').value,
|
| 506 |
+
teacherDesignation: document.getElementById('teacherDesignation').value,
|
| 507 |
+
submissionDate: document.getElementById('submissionDate').value,
|
| 508 |
+
reportType: document.getElementById('reportType').value,
|
| 509 |
+
reportTitle: document.getElementById('reportTitle').value,
|
| 510 |
+
topic: document.getElementById('topic').value,
|
| 511 |
+
includeAbstract: document.getElementById('includeAbstract').checked,
|
| 512 |
+
includeTOC: document.getElementById('includeTOC').checked,
|
| 513 |
+
includeReferences: document.getElementById('includeReferences').checked,
|
| 514 |
+
pageNumbers: document.getElementById('pageNumbers').checked,
|
| 515 |
+
fontFamily: document.getElementById('fontFamily').value,
|
| 516 |
+
fontSize: document.getElementById('fontSize').value,
|
| 517 |
+
lineSpacing: document.getElementById('lineSpacing').value
|
| 518 |
+
};
|
| 519 |
+
|
| 520 |
+
// Show configuration in alert
|
| 521 |
+
alertContainer.innerHTML = `
|
| 522 |
+
<div class="alert success">
|
| 523 |
+
<svg class="icon" fill="#2f855a" viewBox="0 0 24 24">
|
| 524 |
+
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
| 525 |
+
</svg>
|
| 526 |
+
<div>
|
| 527 |
+
<strong style="font-size: 1.1em;">✨ Configuration Saved!</strong><br>
|
| 528 |
+
<small>To generate the actual DOCX file, please run:</small><br>
|
| 529 |
+
<code style="background: rgba(0,0,0,0.1); padding: 5px 10px; border-radius: 5px; display: inline-block; margin-top: 5px;">
|
| 530 |
+
node generate-academic-report.js --config your-config.json
|
| 531 |
+
</code><br>
|
| 532 |
+
<small style="margin-top: 10px; display: block;">
|
| 533 |
+
Your configuration has been prepared. Copy it to a JSON file and use the Node.js backend to generate the DOCX document.
|
| 534 |
+
</small>
|
| 535 |
+
</div>
|
| 536 |
+
</div>
|
| 537 |
+
`;
|
| 538 |
+
|
| 539 |
+
// Download configuration as JSON
|
| 540 |
+
const configJson = JSON.stringify(formData, null, 2);
|
| 541 |
+
const blob = new Blob([configJson], { type: 'application/json' });
|
| 542 |
+
const url = URL.createObjectURL(blob);
|
| 543 |
+
const a = document.createElement('a');
|
| 544 |
+
a.href = url;
|
| 545 |
+
a.download = 'academic-report-config.json';
|
| 546 |
+
document.body.appendChild(a);
|
| 547 |
+
a.click();
|
| 548 |
+
document.body.removeChild(a);
|
| 549 |
+
URL.revokeObjectURL(url);
|
| 550 |
+
|
| 551 |
+
// Re-enable button
|
| 552 |
+
setTimeout(() => {
|
| 553 |
+
generateBtn.disabled = false;
|
| 554 |
+
generateBtn.innerHTML = `
|
| 555 |
+
<svg class="icon" fill="white" viewBox="0 0 24 24">
|
| 556 |
+
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
|
| 557 |
+
</svg>
|
| 558 |
+
Generate Academic Report
|
| 559 |
+
`;
|
| 560 |
+
}, 2000);
|
| 561 |
+
});
|
| 562 |
+
</script>
|
| 563 |
+
</body>
|
| 564 |
+
</html>
|
install.sh
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
|
| 3 |
+
# Smart Academic Report Generator - Installation Script
|
| 4 |
+
# Automated setup for the report generation system
|
| 5 |
+
|
| 6 |
+
# Color codes
|
| 7 |
+
RED='\033[0;31m'
|
| 8 |
+
GREEN='\033[0;32m'
|
| 9 |
+
YELLOW='\033[1;33m'
|
| 10 |
+
BLUE='\033[0;34m'
|
| 11 |
+
CYAN='\033[0;36m'
|
| 12 |
+
NC='\033[0m' # No Color
|
| 13 |
+
|
| 14 |
+
# Banner
|
| 15 |
+
echo -e "${BLUE}"
|
| 16 |
+
cat << "EOF"
|
| 17 |
+
╔══════════════════════════════════════════════════════════╗
|
| 18 |
+
║ ║
|
| 19 |
+
║ 🎓 Smart Academic Report Generator ║
|
| 20 |
+
║ Professional PhD-Level Reports Installer ║
|
| 21 |
+
║ ║
|
| 22 |
+
╚══════════════════════════════════════════════════════════╝
|
| 23 |
+
EOF
|
| 24 |
+
echo -e "${NC}"
|
| 25 |
+
|
| 26 |
+
# Check if running with bash
|
| 27 |
+
if [ -z "$BASH_VERSION" ]; then
|
| 28 |
+
echo -e "${RED}❌ This script must be run with bash${NC}"
|
| 29 |
+
exit 1
|
| 30 |
+
fi
|
| 31 |
+
|
| 32 |
+
echo -e "${CYAN}Starting installation...${NC}\n"
|
| 33 |
+
|
| 34 |
+
# Step 1: Check Node.js
|
| 35 |
+
echo -e "${YELLOW}[1/6]${NC} Checking Node.js installation..."
|
| 36 |
+
if command -v node &> /dev/null; then
|
| 37 |
+
NODE_VERSION=$(node --version)
|
| 38 |
+
echo -e "${GREEN}✅ Node.js is installed: $NODE_VERSION${NC}"
|
| 39 |
+
|
| 40 |
+
# Check version
|
| 41 |
+
REQUIRED_VERSION="16.0.0"
|
| 42 |
+
CURRENT_VERSION=$(node --version | cut -d'v' -f2)
|
| 43 |
+
|
| 44 |
+
if [ "$(printf '%s\n' "$REQUIRED_VERSION" "$CURRENT_VERSION" | sort -V | head -n1)" = "$REQUIRED_VERSION" ]; then
|
| 45 |
+
echo -e "${GREEN} Version is compatible (>= v16.0.0)${NC}"
|
| 46 |
+
else
|
| 47 |
+
echo -e "${YELLOW} ⚠️ Version might be too old. Recommended: >= v16.0.0${NC}"
|
| 48 |
+
fi
|
| 49 |
+
else
|
| 50 |
+
echo -e "${RED}❌ Node.js is not installed${NC}"
|
| 51 |
+
echo -e "${YELLOW} Please install Node.js from: https://nodejs.org/${NC}"
|
| 52 |
+
exit 1
|
| 53 |
+
fi
|
| 54 |
+
|
| 55 |
+
# Step 2: Check npm
|
| 56 |
+
echo -e "\n${YELLOW}[2/6]${NC} Checking npm installation..."
|
| 57 |
+
if command -v npm &> /dev/null; then
|
| 58 |
+
NPM_VERSION=$(npm --version)
|
| 59 |
+
echo -e "${GREEN}✅ npm is installed: v$NPM_VERSION${NC}"
|
| 60 |
+
else
|
| 61 |
+
echo -e "${RED}❌ npm is not installed${NC}"
|
| 62 |
+
echo -e "${YELLOW} npm should come with Node.js. Please reinstall Node.js${NC}"
|
| 63 |
+
exit 1
|
| 64 |
+
fi
|
| 65 |
+
|
| 66 |
+
# Step 3: Install docx package
|
| 67 |
+
echo -e "\n${YELLOW}[3/6]${NC} Installing docx package..."
|
| 68 |
+
if npm list -g docx &> /dev/null; then
|
| 69 |
+
echo -e "${GREEN}✅ docx is already installed globally${NC}"
|
| 70 |
+
else
|
| 71 |
+
echo -e "${CYAN} Installing docx globally...${NC}"
|
| 72 |
+
if npm install -g docx; then
|
| 73 |
+
echo -e "${GREEN}✅ docx installed successfully${NC}"
|
| 74 |
+
else
|
| 75 |
+
echo -e "${YELLOW} ⚠️ Global install failed. Trying local install...${NC}"
|
| 76 |
+
if npm install docx; then
|
| 77 |
+
echo -e "${GREEN}✅ docx installed locally${NC}"
|
| 78 |
+
else
|
| 79 |
+
echo -e "${RED}❌ Failed to install docx${NC}"
|
| 80 |
+
exit 1
|
| 81 |
+
fi
|
| 82 |
+
fi
|
| 83 |
+
fi
|
| 84 |
+
|
| 85 |
+
# Step 4: Verify required files
|
| 86 |
+
echo -e "\n${YELLOW}[4/6]${NC} Verifying required files..."
|
| 87 |
+
REQUIRED_FILES=(
|
| 88 |
+
"generate-academic-report.js"
|
| 89 |
+
"sample-config.json"
|
| 90 |
+
"package.json"
|
| 91 |
+
"README.md"
|
| 92 |
+
"QUICKSTART.md"
|
| 93 |
+
"index.html"
|
| 94 |
+
)
|
| 95 |
+
|
| 96 |
+
MISSING_FILES=0
|
| 97 |
+
for file in "${REQUIRED_FILES[@]}"; do
|
| 98 |
+
if [ -f "$file" ]; then
|
| 99 |
+
echo -e "${GREEN} ✅ $file${NC}"
|
| 100 |
+
else
|
| 101 |
+
echo -e "${RED} ❌ Missing: $file${NC}"
|
| 102 |
+
MISSING_FILES=$((MISSING_FILES + 1))
|
| 103 |
+
fi
|
| 104 |
+
done
|
| 105 |
+
|
| 106 |
+
if [ $MISSING_FILES -gt 0 ]; then
|
| 107 |
+
echo -e "${RED}\n❌ $MISSING_FILES required file(s) missing${NC}"
|
| 108 |
+
echo -e "${YELLOW} Please ensure all files are in the current directory${NC}"
|
| 109 |
+
exit 1
|
| 110 |
+
fi
|
| 111 |
+
|
| 112 |
+
# Step 5: Create output directory
|
| 113 |
+
echo -e "\n${YELLOW}[5/6]${NC} Setting up output directory..."
|
| 114 |
+
OUTPUT_DIR="/mnt/user-data/outputs"
|
| 115 |
+
|
| 116 |
+
if [ -d "$OUTPUT_DIR" ]; then
|
| 117 |
+
echo -e "${GREEN}✅ Output directory exists: $OUTPUT_DIR${NC}"
|
| 118 |
+
else
|
| 119 |
+
echo -e "${CYAN} Creating output directory...${NC}"
|
| 120 |
+
if mkdir -p "$OUTPUT_DIR" 2>/dev/null; then
|
| 121 |
+
echo -e "${GREEN}✅ Output directory created${NC}"
|
| 122 |
+
else
|
| 123 |
+
echo -e "${YELLOW} ⚠️ Could not create $OUTPUT_DIR${NC}"
|
| 124 |
+
echo -e "${YELLOW} Will use current directory instead${NC}"
|
| 125 |
+
OUTPUT_DIR="./outputs"
|
| 126 |
+
mkdir -p "$OUTPUT_DIR"
|
| 127 |
+
fi
|
| 128 |
+
fi
|
| 129 |
+
|
| 130 |
+
# Make scripts executable
|
| 131 |
+
echo -e "\n${YELLOW}[6/6]${NC} Setting file permissions..."
|
| 132 |
+
chmod +x generate-academic-report.js 2>/dev/null
|
| 133 |
+
chmod +x test-suite.js 2>/dev/null
|
| 134 |
+
echo -e "${GREEN}✅ Permissions set${NC}"
|
| 135 |
+
|
| 136 |
+
# Success summary
|
| 137 |
+
echo -e "\n${GREEN}╔══════════════════════════════════════════════════════════╗${NC}"
|
| 138 |
+
echo -e "${GREEN}║ ║${NC}"
|
| 139 |
+
echo -e "${GREEN}║ ✅ Installation completed successfully! ║${NC}"
|
| 140 |
+
echo -e "${GREEN}║ ║${NC}"
|
| 141 |
+
echo -e "${GREEN}╚══════════════════════════════════════════════════════════╝${NC}"
|
| 142 |
+
|
| 143 |
+
# Next steps
|
| 144 |
+
echo -e "\n${CYAN}📚 Next Steps:${NC}\n"
|
| 145 |
+
echo -e "${YELLOW}1.${NC} Test the installation:"
|
| 146 |
+
echo -e " ${CYAN}node generate-academic-report.js --config sample-config.json${NC}\n"
|
| 147 |
+
|
| 148 |
+
echo -e "${YELLOW}2.${NC} Run the test suite:"
|
| 149 |
+
echo -e " ${CYAN}node test-suite.js${NC}\n"
|
| 150 |
+
|
| 151 |
+
echo -e "${YELLOW}3.${NC} Create your first report:"
|
| 152 |
+
echo -e " ${CYAN}cp sample-config.json my-config.json${NC}"
|
| 153 |
+
echo -e " ${CYAN}# Edit my-config.json with your details${NC}"
|
| 154 |
+
echo -e " ${CYAN}node generate-academic-report.js --config my-config.json${NC}\n"
|
| 155 |
+
|
| 156 |
+
echo -e "${YELLOW}4.${NC} Open HTML interface:"
|
| 157 |
+
echo -e " ${CYAN}Open index.html in your web browser${NC}\n"
|
| 158 |
+
|
| 159 |
+
echo -e "${CYAN}📖 Documentation:${NC}"
|
| 160 |
+
echo -e " • README.md - Complete documentation"
|
| 161 |
+
echo -e " • QUICKSTART.md - Quick reference guide"
|
| 162 |
+
echo -e " • EXAMPLES.md - Usage examples & tutorials"
|
| 163 |
+
|
| 164 |
+
echo -e "\n${CYAN}🎓 Happy Report Writing!${NC}\n"
|
| 165 |
+
|
| 166 |
+
# Optional: Run test
|
| 167 |
+
echo -e "${YELLOW}Would you like to run a test now? (y/n)${NC} "
|
| 168 |
+
read -r -n 1 response
|
| 169 |
+
echo
|
| 170 |
+
|
| 171 |
+
if [[ "$response" =~ ^[Yy]$ ]]; then
|
| 172 |
+
echo -e "\n${CYAN}Running test...${NC}\n"
|
| 173 |
+
node test-suite.js
|
| 174 |
+
|
| 175 |
+
if [ $? -eq 0 ]; then
|
| 176 |
+
echo -e "\n${GREEN}✅ Test passed! You're ready to generate reports.${NC}\n"
|
| 177 |
+
else
|
| 178 |
+
echo -e "\n${RED}❌ Test failed. Please check the error messages above.${NC}\n"
|
| 179 |
+
fi
|
| 180 |
+
else
|
| 181 |
+
echo -e "${YELLOW}Skipping test. Run 'node test-suite.js' anytime to verify.${NC}\n"
|
| 182 |
+
fi
|
| 183 |
+
|
| 184 |
+
exit 0
|
package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "smart-academic-report-generator",
|
| 3 |
+
"version": "1.0.0",
|
| 4 |
+
"description": "Professional PhD-Level Academic Reports Generator with Auto Cover Page, TOC, and Complete Structure",
|
| 5 |
+
"main": "generate-academic-report.js",
|
| 6 |
+
"scripts": {
|
| 7 |
+
"generate": "node generate-academic-report.js --config sample-config.json",
|
| 8 |
+
"generate:custom": "node generate-academic-report.js --config",
|
| 9 |
+
"start": "react-scripts start",
|
| 10 |
+
"build": "react-scripts build",
|
| 11 |
+
"test": "node generate-academic-report.js --config sample-config.json && echo '✅ Test completed successfully!'"
|
| 12 |
+
},
|
| 13 |
+
"keywords": [
|
| 14 |
+
"academic",
|
| 15 |
+
"report",
|
| 16 |
+
"generator",
|
| 17 |
+
"docx",
|
| 18 |
+
"university",
|
| 19 |
+
"thesis",
|
| 20 |
+
"assignment",
|
| 21 |
+
"phd",
|
| 22 |
+
"research",
|
| 23 |
+
"paper",
|
| 24 |
+
"automation",
|
| 25 |
+
"cover-page",
|
| 26 |
+
"table-of-contents",
|
| 27 |
+
"references",
|
| 28 |
+
"apa",
|
| 29 |
+
"student",
|
| 30 |
+
"education"
|
| 31 |
+
],
|
| 32 |
+
"author": "Smart Academic Tools",
|
| 33 |
+
"license": "MIT",
|
| 34 |
+
"dependencies": {
|
| 35 |
+
"docx": "^8.5.0"
|
| 36 |
+
},
|
| 37 |
+
"devDependencies": {
|
| 38 |
+
"react": "^18.2.0",
|
| 39 |
+
"react-dom": "^18.2.0",
|
| 40 |
+
"react-scripts": "^5.0.1",
|
| 41 |
+
"lucide-react": "^0.263.1"
|
| 42 |
+
},
|
| 43 |
+
"engines": {
|
| 44 |
+
"node": ">=16.0.0",
|
| 45 |
+
"npm": ">=8.0.0"
|
| 46 |
+
},
|
| 47 |
+
"repository": {
|
| 48 |
+
"type": "git",
|
| 49 |
+
"url": "https://github.com/yourusername/smart-academic-report-generator"
|
| 50 |
+
},
|
| 51 |
+
"bugs": {
|
| 52 |
+
"url": "https://github.com/yourusername/smart-academic-report-generator/issues"
|
| 53 |
+
},
|
| 54 |
+
"homepage": "https://github.com/yourusername/smart-academic-report-generator#readme"
|
| 55 |
+
}
|
sample-config.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"studentName": "Md. Rahman Ahmed",
|
| 3 |
+
"studentId": "2023-1-60-001",
|
| 4 |
+
"department": "Computer Science & Engineering",
|
| 5 |
+
"university": "East West University",
|
| 6 |
+
"courseTitle": "Artificial Intelligence",
|
| 7 |
+
"courseCode": "CSE 366",
|
| 8 |
+
"teacherName": "Dr. Sarah Johnson",
|
| 9 |
+
"teacherDesignation": "Associate Professor",
|
| 10 |
+
"submissionDate": "2026-02-14",
|
| 11 |
+
"reportType": "assignment",
|
| 12 |
+
"reportTitle": "Deep Learning Applications in Medical Imaging",
|
| 13 |
+
"topic": "Comprehensive Analysis of Convolutional Neural Networks for Detecting Lung Cancer from CT Scans",
|
| 14 |
+
"includeAbstract": true,
|
| 15 |
+
"includeTOC": true,
|
| 16 |
+
"includeReferences": true,
|
| 17 |
+
"pageNumbers": true,
|
| 18 |
+
"fontFamily": "Times New Roman",
|
| 19 |
+
"fontSize": "12",
|
| 20 |
+
"lineSpacing": "1.5"
|
| 21 |
+
}
|
test-suite.js
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env node
|
| 2 |
+
|
| 3 |
+
/**
|
| 4 |
+
* Test Suite for Smart Academic Report Generator
|
| 5 |
+
* Validates all features and configurations
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
const fs = require('fs');
|
| 9 |
+
const path = require('path');
|
| 10 |
+
|
| 11 |
+
// ANSI color codes for console output
|
| 12 |
+
const colors = {
|
| 13 |
+
reset: '\x1b[0m',
|
| 14 |
+
bright: '\x1b[1m',
|
| 15 |
+
green: '\x1b[32m',
|
| 16 |
+
red: '\x1b[31m',
|
| 17 |
+
yellow: '\x1b[33m',
|
| 18 |
+
blue: '\x1b[34m',
|
| 19 |
+
cyan: '\x1b[36m'
|
| 20 |
+
};
|
| 21 |
+
|
| 22 |
+
function log(message, color = 'reset') {
|
| 23 |
+
console.log(`${colors[color]}${message}${colors.reset}`);
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
function logSuccess(message) {
|
| 27 |
+
log(`✅ ${message}`, 'green');
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
function logError(message) {
|
| 31 |
+
log(`❌ ${message}`, 'red');
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
function logInfo(message) {
|
| 35 |
+
log(`ℹ️ ${message}`, 'cyan');
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
function logWarning(message) {
|
| 39 |
+
log(`⚠️ ${message}`, 'yellow');
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
function logHeader(message) {
|
| 43 |
+
log(`\n${'='.repeat(60)}`, 'blue');
|
| 44 |
+
log(message, 'bright');
|
| 45 |
+
log('='.repeat(60), 'blue');
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
// Test cases
|
| 49 |
+
const tests = {
|
| 50 |
+
passed: 0,
|
| 51 |
+
failed: 0,
|
| 52 |
+
total: 0
|
| 53 |
+
};
|
| 54 |
+
|
| 55 |
+
function runTest(testName, testFn) {
|
| 56 |
+
tests.total++;
|
| 57 |
+
try {
|
| 58 |
+
testFn();
|
| 59 |
+
tests.passed++;
|
| 60 |
+
logSuccess(`${testName}`);
|
| 61 |
+
return true;
|
| 62 |
+
} catch (error) {
|
| 63 |
+
tests.failed++;
|
| 64 |
+
logError(`${testName}`);
|
| 65 |
+
logError(` Error: ${error.message}`);
|
| 66 |
+
return false;
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
// Test 1: Check if required files exist
|
| 71 |
+
function testFilesExist() {
|
| 72 |
+
logHeader('Test 1: Checking Required Files');
|
| 73 |
+
|
| 74 |
+
const requiredFiles = [
|
| 75 |
+
'generate-academic-report.js',
|
| 76 |
+
'sample-config.json',
|
| 77 |
+
'package.json',
|
| 78 |
+
'README.md',
|
| 79 |
+
'QUICKSTART.md',
|
| 80 |
+
'index.html'
|
| 81 |
+
];
|
| 82 |
+
|
| 83 |
+
requiredFiles.forEach(file => {
|
| 84 |
+
runTest(`File exists: ${file}`, () => {
|
| 85 |
+
if (!fs.existsSync(file)) {
|
| 86 |
+
throw new Error(`File not found: ${file}`);
|
| 87 |
+
}
|
| 88 |
+
});
|
| 89 |
+
});
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
// Test 2: Validate sample configuration
|
| 93 |
+
function testSampleConfig() {
|
| 94 |
+
logHeader('Test 2: Validating Sample Configuration');
|
| 95 |
+
|
| 96 |
+
runTest('sample-config.json is valid JSON', () => {
|
| 97 |
+
const content = fs.readFileSync('sample-config.json', 'utf8');
|
| 98 |
+
const config = JSON.parse(content);
|
| 99 |
+
|
| 100 |
+
// Check required fields
|
| 101 |
+
const requiredFields = [
|
| 102 |
+
'studentName', 'studentId', 'department', 'university',
|
| 103 |
+
'courseTitle', 'courseCode', 'teacherName', 'reportTitle', 'topic'
|
| 104 |
+
];
|
| 105 |
+
|
| 106 |
+
requiredFields.forEach(field => {
|
| 107 |
+
if (!config[field]) {
|
| 108 |
+
throw new Error(`Missing required field: ${field}`);
|
| 109 |
+
}
|
| 110 |
+
});
|
| 111 |
+
});
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
// Test 3: Validate package.json
|
| 115 |
+
function testPackageJson() {
|
| 116 |
+
logHeader('Test 3: Validating package.json');
|
| 117 |
+
|
| 118 |
+
runTest('package.json is valid', () => {
|
| 119 |
+
const content = fs.readFileSync('package.json', 'utf8');
|
| 120 |
+
const pkg = JSON.parse(content);
|
| 121 |
+
|
| 122 |
+
if (!pkg.name) throw new Error('Missing package name');
|
| 123 |
+
if (!pkg.version) throw new Error('Missing version');
|
| 124 |
+
if (!pkg.dependencies) throw new Error('Missing dependencies');
|
| 125 |
+
if (!pkg.dependencies.docx) throw new Error('Missing docx dependency');
|
| 126 |
+
});
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
// Test 4: Check script permissions
|
| 130 |
+
function testScriptPermissions() {
|
| 131 |
+
logHeader('Test 4: Checking Script Permissions');
|
| 132 |
+
|
| 133 |
+
runTest('generate-academic-report.js is readable', () => {
|
| 134 |
+
try {
|
| 135 |
+
fs.accessSync('generate-academic-report.js', fs.constants.R_OK);
|
| 136 |
+
} catch (err) {
|
| 137 |
+
throw new Error('Script is not readable');
|
| 138 |
+
}
|
| 139 |
+
});
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
// Test 5: Validate configuration options
|
| 143 |
+
function testConfigurationOptions() {
|
| 144 |
+
logHeader('Test 5: Testing Configuration Options');
|
| 145 |
+
|
| 146 |
+
const testConfigs = [
|
| 147 |
+
{
|
| 148 |
+
name: 'Minimum config',
|
| 149 |
+
config: {
|
| 150 |
+
studentName: 'Test Student',
|
| 151 |
+
studentId: 'TEST-001',
|
| 152 |
+
department: 'Test Dept',
|
| 153 |
+
university: 'Test University',
|
| 154 |
+
courseTitle: 'Test Course',
|
| 155 |
+
courseCode: 'TST 101',
|
| 156 |
+
teacherName: 'Test Teacher',
|
| 157 |
+
reportTitle: 'Test Report',
|
| 158 |
+
topic: 'Test Topic'
|
| 159 |
+
}
|
| 160 |
+
},
|
| 161 |
+
{
|
| 162 |
+
name: 'Full config with all options',
|
| 163 |
+
config: {
|
| 164 |
+
studentName: 'Test Student',
|
| 165 |
+
studentId: 'TEST-001',
|
| 166 |
+
department: 'Test Dept',
|
| 167 |
+
university: 'Test University',
|
| 168 |
+
courseTitle: 'Test Course',
|
| 169 |
+
courseCode: 'TST 101',
|
| 170 |
+
teacherName: 'Test Teacher',
|
| 171 |
+
teacherDesignation: 'Professor',
|
| 172 |
+
submissionDate: '2026-02-14',
|
| 173 |
+
reportType: 'assignment',
|
| 174 |
+
reportTitle: 'Test Report',
|
| 175 |
+
topic: 'Test Topic',
|
| 176 |
+
includeAbstract: true,
|
| 177 |
+
includeTOC: true,
|
| 178 |
+
includeReferences: true,
|
| 179 |
+
pageNumbers: true,
|
| 180 |
+
fontFamily: 'Times New Roman',
|
| 181 |
+
fontSize: '12',
|
| 182 |
+
lineSpacing: '1.5'
|
| 183 |
+
}
|
| 184 |
+
}
|
| 185 |
+
];
|
| 186 |
+
|
| 187 |
+
testConfigs.forEach(({ name, config }) => {
|
| 188 |
+
runTest(`Config validation: ${name}`, () => {
|
| 189 |
+
const jsonStr = JSON.stringify(config, null, 2);
|
| 190 |
+
JSON.parse(jsonStr); // Validate it's proper JSON
|
| 191 |
+
});
|
| 192 |
+
});
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
// Test 6: Test different report types
|
| 196 |
+
function testReportTypes() {
|
| 197 |
+
logHeader('Test 6: Testing Report Types');
|
| 198 |
+
|
| 199 |
+
const reportTypes = [
|
| 200 |
+
'assignment',
|
| 201 |
+
'project',
|
| 202 |
+
'thesis',
|
| 203 |
+
'research',
|
| 204 |
+
'case-study',
|
| 205 |
+
'lab-report'
|
| 206 |
+
];
|
| 207 |
+
|
| 208 |
+
reportTypes.forEach(type => {
|
| 209 |
+
runTest(`Report type: ${type}`, () => {
|
| 210 |
+
// Just validate the type is a string
|
| 211 |
+
if (typeof type !== 'string') {
|
| 212 |
+
throw new Error(`Invalid report type: ${type}`);
|
| 213 |
+
}
|
| 214 |
+
});
|
| 215 |
+
});
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
// Test 7: Test font families
|
| 219 |
+
function testFontFamilies() {
|
| 220 |
+
logHeader('Test 7: Testing Font Families');
|
| 221 |
+
|
| 222 |
+
const fontFamilies = [
|
| 223 |
+
'Times New Roman',
|
| 224 |
+
'Arial',
|
| 225 |
+
'Calibri',
|
| 226 |
+
'Georgia'
|
| 227 |
+
];
|
| 228 |
+
|
| 229 |
+
fontFamilies.forEach(font => {
|
| 230 |
+
runTest(`Font family: ${font}`, () => {
|
| 231 |
+
if (typeof font !== 'string' || font.length === 0) {
|
| 232 |
+
throw new Error(`Invalid font family: ${font}`);
|
| 233 |
+
}
|
| 234 |
+
});
|
| 235 |
+
});
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
// Test 8: Test date formats
|
| 239 |
+
function testDateFormats() {
|
| 240 |
+
logHeader('Test 8: Testing Date Formats');
|
| 241 |
+
|
| 242 |
+
const testDates = [
|
| 243 |
+
{ date: '2026-02-14', valid: true, name: 'ISO format (YYYY-MM-DD)' },
|
| 244 |
+
{ date: '2026-12-31', valid: true, name: 'End of year' },
|
| 245 |
+
{ date: '2026-01-01', valid: true, name: 'Start of year' }
|
| 246 |
+
];
|
| 247 |
+
|
| 248 |
+
testDates.forEach(({ date, valid, name }) => {
|
| 249 |
+
runTest(`Date format: ${name}`, () => {
|
| 250 |
+
const d = new Date(date);
|
| 251 |
+
if (isNaN(d.getTime()) && valid) {
|
| 252 |
+
throw new Error(`Invalid date: ${date}`);
|
| 253 |
+
}
|
| 254 |
+
});
|
| 255 |
+
});
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
// Test 9: Output directory check
|
| 259 |
+
function testOutputDirectory() {
|
| 260 |
+
logHeader('Test 9: Checking Output Directory');
|
| 261 |
+
|
| 262 |
+
runTest('Output directory structure', () => {
|
| 263 |
+
const outputDir = '/mnt/user-data/outputs';
|
| 264 |
+
// Just check if we can create the path conceptually
|
| 265 |
+
const isValidPath = outputDir.startsWith('/');
|
| 266 |
+
if (!isValidPath) {
|
| 267 |
+
throw new Error('Invalid output path');
|
| 268 |
+
}
|
| 269 |
+
});
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
// Test 10: Documentation completeness
|
| 273 |
+
function testDocumentation() {
|
| 274 |
+
logHeader('Test 10: Checking Documentation');
|
| 275 |
+
|
| 276 |
+
const docs = [
|
| 277 |
+
{ file: 'README.md', minLength: 1000 },
|
| 278 |
+
{ file: 'QUICKSTART.md', minLength: 500 }
|
| 279 |
+
];
|
| 280 |
+
|
| 281 |
+
docs.forEach(({ file, minLength }) => {
|
| 282 |
+
runTest(`Documentation: ${file}`, () => {
|
| 283 |
+
const content = fs.readFileSync(file, 'utf8');
|
| 284 |
+
if (content.length < minLength) {
|
| 285 |
+
throw new Error(`${file} seems incomplete (${content.length} chars)`);
|
| 286 |
+
}
|
| 287 |
+
});
|
| 288 |
+
});
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
// Test 11: HTML interface validation
|
| 292 |
+
function testHTMLInterface() {
|
| 293 |
+
logHeader('Test 11: Validating HTML Interface');
|
| 294 |
+
|
| 295 |
+
runTest('index.html structure', () => {
|
| 296 |
+
const content = fs.readFileSync('index.html', 'utf8');
|
| 297 |
+
|
| 298 |
+
// Check for essential elements
|
| 299 |
+
const requiredElements = [
|
| 300 |
+
'<form',
|
| 301 |
+
'studentName',
|
| 302 |
+
'studentId',
|
| 303 |
+
'department',
|
| 304 |
+
'university',
|
| 305 |
+
'courseTitle',
|
| 306 |
+
'reportTitle',
|
| 307 |
+
'submit'
|
| 308 |
+
];
|
| 309 |
+
|
| 310 |
+
requiredElements.forEach(element => {
|
| 311 |
+
if (!content.includes(element)) {
|
| 312 |
+
throw new Error(`Missing element in HTML: ${element}`);
|
| 313 |
+
}
|
| 314 |
+
});
|
| 315 |
+
});
|
| 316 |
+
}
|
| 317 |
+
|
| 318 |
+
// Test 12: Configuration field types
|
| 319 |
+
function testConfigFieldTypes() {
|
| 320 |
+
logHeader('Test 12: Testing Configuration Field Types');
|
| 321 |
+
|
| 322 |
+
runTest('String fields validation', () => {
|
| 323 |
+
const stringFields = [
|
| 324 |
+
'studentName', 'studentId', 'department', 'university',
|
| 325 |
+
'courseTitle', 'courseCode', 'teacherName', 'reportTitle', 'topic'
|
| 326 |
+
];
|
| 327 |
+
|
| 328 |
+
stringFields.forEach(field => {
|
| 329 |
+
const value = 'Test Value';
|
| 330 |
+
if (typeof value !== 'string') {
|
| 331 |
+
throw new Error(`Field ${field} should be string`);
|
| 332 |
+
}
|
| 333 |
+
});
|
| 334 |
+
});
|
| 335 |
+
|
| 336 |
+
runTest('Boolean fields validation', () => {
|
| 337 |
+
const booleanFields = [
|
| 338 |
+
'includeAbstract', 'includeTOC', 'includeReferences', 'pageNumbers'
|
| 339 |
+
];
|
| 340 |
+
|
| 341 |
+
booleanFields.forEach(field => {
|
| 342 |
+
const value = true;
|
| 343 |
+
if (typeof value !== 'boolean') {
|
| 344 |
+
throw new Error(`Field ${field} should be boolean`);
|
| 345 |
+
}
|
| 346 |
+
});
|
| 347 |
+
});
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
// Main test execution
|
| 351 |
+
function runAllTests() {
|
| 352 |
+
console.clear();
|
| 353 |
+
logHeader('🎓 Smart Academic Report Generator - Test Suite');
|
| 354 |
+
logInfo('Running comprehensive tests...\n');
|
| 355 |
+
|
| 356 |
+
// Run all test suites
|
| 357 |
+
testFilesExist();
|
| 358 |
+
testSampleConfig();
|
| 359 |
+
testPackageJson();
|
| 360 |
+
testScriptPermissions();
|
| 361 |
+
testConfigurationOptions();
|
| 362 |
+
testReportTypes();
|
| 363 |
+
testFontFamilies();
|
| 364 |
+
testDateFormats();
|
| 365 |
+
testOutputDirectory();
|
| 366 |
+
testDocumentation();
|
| 367 |
+
testHTMLInterface();
|
| 368 |
+
testConfigFieldTypes();
|
| 369 |
+
|
| 370 |
+
// Print summary
|
| 371 |
+
logHeader('Test Summary');
|
| 372 |
+
log(`\nTotal Tests: ${tests.total}`, 'bright');
|
| 373 |
+
logSuccess(`Passed: ${tests.passed}`);
|
| 374 |
+
|
| 375 |
+
if (tests.failed > 0) {
|
| 376 |
+
logError(`Failed: ${tests.failed}`);
|
| 377 |
+
log(`\nSuccess Rate: ${((tests.passed / tests.total) * 100).toFixed(1)}%`, 'yellow');
|
| 378 |
+
process.exit(1);
|
| 379 |
+
} else {
|
| 380 |
+
log('\n🎉 All tests passed! System is ready to use.', 'green');
|
| 381 |
+
log('\nTo generate a report, run:', 'cyan');
|
| 382 |
+
log(' node generate-academic-report.js --config sample-config.json\n', 'bright');
|
| 383 |
+
process.exit(0);
|
| 384 |
+
}
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
// Run tests
|
| 388 |
+
if (require.main === module) {
|
| 389 |
+
runAllTests();
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
module.exports = { runAllTests };
|