diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 7d63b84..d2739d4 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -12,6 +12,7 @@ jobs: permissions: contents: read + pull-requests: write steps: - name: Checkout diff --git a/src/app/ai-generator/page.tsx b/src/app/ai-generator/page.tsx index 2631199..a2eb5ac 100644 --- a/src/app/ai-generator/page.tsx +++ b/src/app/ai-generator/page.tsx @@ -1,4 +1,4 @@ -'use client'; +'use client'; import { useState } from 'react'; import { Button } from '@/components/ui/button'; @@ -7,11 +7,13 @@ import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; -import { Download, FileText, Loader2, Sparkles, Brain, Upload, X, Send, MessageSquare, Plus } from 'lucide-react'; +import { Download, FileText, Loader2, Sparkles, Upload, X, Send, MessageSquare, Plus, Brain } from 'lucide-react'; import { exportToPDF, exportToWord } from '@/lib/document-utils'; import Aurora from '@/components/Backgrounds/Aurora'; +import { NavbarDemo } from '@/components/nav'; +import Footer from '@/components/footer'; export default function AIGenerator() { const [formData, setFormData] = useState({ @@ -95,7 +97,6 @@ export default function AIGenerator() { setGeneratedContent(cleanContent); setStatusMessage({type: 'success', text: 'Assignment generated successfully!'}); setChatMessages([]); - setShowChat(true); updateUsage('generation'); } catch (error) { @@ -133,16 +134,16 @@ export default function AIGenerator() { }); const data = await response.json(); - if (data.error) throw new Error(data.error); + if (data.error) throw new Error(data.error as string); // Add assistant response and update content if modified setChatMessages(prev => [...prev, { role: 'assistant', content: data.response }]); if (data.updatedContent) { setGeneratedContent(data.updatedContent); } - // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (error) { - setChatMessages(prev => [...prev, { role: 'assistant', content: 'Sorry, I encountered an error. Please try again.' }]); + const errorMsg = (error as Error).message || 'Unknown error'; + setChatMessages(prev => [...prev, { role: 'assistant', content: `Sorry, I encountered an error: ${errorMsg}. Please try again.` }]); } finally { setIsChatting(false); } @@ -185,6 +186,8 @@ export default function AIGenerator() { return (
+ {/* Navbar */} + {/* Simple Header */}
@@ -211,7 +214,7 @@ export default function AIGenerator() { />
-
+
{/* Hero Section */}
@@ -263,6 +266,7 @@ export default function AIGenerator() { onChange={(e) => setFormData({...formData, topic: e.target.value})} placeholder="Enter assignment topic" className="bg-white/10 border-white/20 text-white placeholder:text-white/60" + suppressHydrationWarning />
@@ -274,6 +278,7 @@ export default function AIGenerator() { onChange={(e) => setFormData({...formData, subject: e.target.value})} placeholder="e.g., Computer Science, History" className="bg-white/10 border-white/20 text-white placeholder:text-white/60" + suppressHydrationWarning />
@@ -344,6 +349,7 @@ export default function AIGenerator() { onChange={(e) => setFormData({...formData, imageQuery: e.target.value})} placeholder="e.g., sunflower, DNA structure, solar system" className="bg-white/10 border-white/20 text-white placeholder:text-white/60" + suppressHydrationWarning />
)} @@ -487,6 +493,7 @@ export default function AIGenerator() {

Ask me to modify your assignment!

+

Try: "Make it shorter" or "Add examples"

Try: “Make it shorter” or “Add examples”

) : ( @@ -520,6 +527,7 @@ export default function AIGenerator() { className="bg-white/10 border-white/20 text-white placeholder:text-white/60 text-sm" onKeyPress={(e) => e.key === 'Enter' && !e.shiftKey && handleChatSubmit()} disabled={isChatting} + suppressHydrationWarning />
+ + {/* Footer */} +
); } diff --git a/src/app/api/chat-assignment/route.ts b/src/app/api/chat-assignment/route.ts index f6d61ca..a43d7db 100644 --- a/src/app/api/chat-assignment/route.ts +++ b/src/app/api/chat-assignment/route.ts @@ -79,6 +79,7 @@ Please provide a helpful response about the assignment. If the user is asking fo } catch (error: unknown) { console.error('Chat error:', error); return NextResponse.json({ + error: error instanceof Error ? error.message : 'Failed to process chat request' error: (error as Error).message || 'Failed to process chat request' }, { status: 500 }); } diff --git a/src/app/api/export-document/route.ts b/src/app/api/export-document/route.ts index 0c010f7..dbcad70 100644 --- a/src/app/api/export-document/route.ts +++ b/src/app/api/export-document/route.ts @@ -22,6 +22,7 @@ export async function POST(req: NextRequest) { filename: `${title || 'assignment'}.pdf` }); } catch (error: unknown) { + return NextResponse.json({ error: error instanceof Error ? error.message : 'Export failed' }, { status: 500 }); return NextResponse.json({ error: (error as Error).message || 'Export failed' }, { status: 500 }); } } \ No newline at end of file diff --git a/src/app/api/fetch-image/route.ts b/src/app/api/fetch-image/route.ts index f6d4560..9862069 100644 --- a/src/app/api/fetch-image/route.ts +++ b/src/app/api/fetch-image/route.ts @@ -40,6 +40,7 @@ export async function POST(req: NextRequest) { return NextResponse.json({ error: 'No images found' }, { status: 404 }); } catch (error: unknown) { + return NextResponse.json({ error: error instanceof Error ? error.message : 'Image fetch failed' }, { status: 500 }); return NextResponse.json({ error: (error as Error).message || 'Image fetch failed' }, { status: 500 }); } } \ No newline at end of file diff --git a/src/app/api/generate-assignment/route.ts b/src/app/api/generate-assignment/route.ts index 9902029..0eac74b 100644 --- a/src/app/api/generate-assignment/route.ts +++ b/src/app/api/generate-assignment/route.ts @@ -62,12 +62,8 @@ export async function POST(req: NextRequest) { for (const [, file] of files) { if (file instanceof File) { - try { - const text = await file.text(); - fileContent += `\n\nReference from ${file.name}:\n${text}\n`; - } catch (error) { - console.error(`Failed to read file ${file.name}:`, error); - } + const text = await file.text(); + fileContent += `\n--- Content from ${file.name} ---\n${text}\n\n`; } } @@ -76,6 +72,8 @@ export async function POST(req: NextRequest) { const prompt = `Generate a comprehensive academic assignment on "${topic}" for ${subject} at ${level || 'undergraduate'} level. Target word count: ${wordCount || 1000} words. ${requirements ? `Additional requirements: ${requirements}` : ''} + ${fileContent ? `\nReference materials:\n${fileContent}` : ''} + ${fileContent ? `\n\nReference materials provided:\n${fileContent}\n\nPlease incorporate relevant information from these reference materials into the assignment.` : ''} Structure the assignment with: @@ -85,6 +83,29 @@ export async function POST(req: NextRequest) { 4. Conclusion 5. References (if applicable) + Format the response as structured HTML with proper headings, paragraphs, and formatting.`; + + const result = await model.generateContent(prompt); + const content = result.response.text(); + + // Fetch image if requested + let finalContent = content; + if (includeImages && imageQuery) { + const imageData = await fetchRelevantImage(imageQuery); + if (imageData) { + finalContent = `
+ ${imageData.alt} +
\n${content}`; + } + } + + return NextResponse.json({ content: finalContent }); + } catch (error: unknown) { + console.error('Assignment generation failed:', error); + const errorObj = error as Error; + const errorMessage = errorObj.message?.includes('limit') || errorObj.message?.includes('quota') + ? 'Your limit for today has exceeded. Please try again tomorrow.' + : errorObj.message || 'Assignment generation failed'; ${includeImages ? `Also suggest 1 relevant image search term that would enhance this assignment. Use the main topic "${topic}" as the search term unless a more specific term would be better. Add this term as a JSON array in an HTML comment at the very end: ` : ''} Format the response as structured HTML with proper headings, paragraphs, and formatting.`; diff --git a/src/app/contact/page.tsx b/src/app/contact/page.tsx new file mode 100644 index 0000000..d4d6a45 --- /dev/null +++ b/src/app/contact/page.tsx @@ -0,0 +1,281 @@ +"use client"; +import React, { useState, useEffect } from "react"; +import { Boxes } from "@/components/ui/background-boxes"; +import { NavbarDemo } from "@/components/nav"; +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; +import { cn } from "@/lib/utils"; +import { Mail, Phone, MapPin, Send } from "lucide-react"; +import { DotLottieReact } from "@lottiefiles/dotlottie-react"; + +export default function ContactPage() { + const [isLoading, setIsLoading] = useState(true); + const [mounted, setMounted] = useState(false); + const [formData, setFormData] = useState({ + name: "", + email: "", + subject: "", + message: "" + }); + const [isSubmitting, setIsSubmitting] = useState(false); + const [submitStatus, setSubmitStatus] = useState<"idle" | "success" | "error">("idle"); + + useEffect(() => { + setMounted(true); + }, []); + + useEffect(() => { + if (!mounted) return; + const timer = setTimeout(() => { + setIsLoading(false); + }, 2000); + return () => clearTimeout(timer); + }, [mounted]); + + const handleInputChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setFormData(prev => ({ + ...prev, + [name]: value + })); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setIsSubmitting(true); + + // Simulate form submission + try { + await new Promise(resolve => setTimeout(resolve, 2000)); + setSubmitStatus("success"); + setFormData({ name: "", email: "", subject: "", message: "" }); + } catch { + setSubmitStatus("error"); + } finally { + setIsSubmitting(false); + } + }; + + if (!mounted) return null; + + return ( +
+ + {/* Loading Screen */} + {isLoading && ( +
+
+ +

Loading...

+
+
+ )} + + + +
+ + + + {/* Main Content */} +
+ {!isLoading && ( +
+ {/* Header Section */} +
+

+ Get in Touch +

+

+ Have questions about our services? We'd love to hear from you. Send us a message and we'll respond as soon as possible. +

+
+ +
+ {/* Contact Information */} +
+
+

Contact Information

+
+
+
+
+ +
+
+

Phone

+

+1 (555) 123-4567

+
+
+ +
+
+ +
+
+

Email

+

support@asshelp.com

+
+
+
+ +
+
+ +
+
+

Address

+

123 Assignment Street
Help City, HC 12345

+
+
+
+
+ + {/* FAQ Section */} +
+

Frequently Asked Questions

+
+
+

What subjects do you cover?

+

We cover all major academic subjects including STEM, humanities, business, and more.

+
+
+

Is the work plagiarism-free?

+

Yes, all our work is 100% original and plagiarism-free with detailed citations.

+
+
+
+
+ + {/* Contact Form */} +
+

Send us a Message

+ + {submitStatus === "success" && ( +
+

Thank you! Your message has been sent successfully.

+
+ )} + + {submitStatus === "error" && ( +
+

Sorry, there was an error sending your message. Please try again.

+
+ )} + +
+
+ + + + + + + + + +
+ + + + + + + + +