mirror of
https://github.com/PinkSheep27/SBU-Hackathon.git
synced 2026-10-11 00:30:26 -04:00
Fixed commented out programs
This commit is contained in:
+262
-262
@@ -1,294 +1,294 @@
|
||||
// "use client";
|
||||
"use client";
|
||||
|
||||
// import React, { useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
// import {
|
||||
// FormData,
|
||||
// PROFICIENCY_LEVELS
|
||||
// } from './formTypes'; // Ensure path is correct
|
||||
import {
|
||||
FormData,
|
||||
PROFICIENCY_LEVELS
|
||||
} from './formTypes'; // Ensure path is correct
|
||||
|
||||
// interface FormPageProps {
|
||||
// onFormSubmit: (data: FormData) => void;
|
||||
// }
|
||||
interface FormPageProps {
|
||||
onFormSubmit: (data: FormData) => void;
|
||||
}
|
||||
|
||||
// const FormPage: React.FC<FormPageProps> = ({ onFormSubmit }) => {
|
||||
// const [formData, setFormData] = useState<FormData>({
|
||||
// Hackathon: '',
|
||||
// mainTheme: '',
|
||||
// tracksStack: [''],
|
||||
// students: [{
|
||||
// studentName: '',
|
||||
// skills: [{ skillName: '', proficiency: PROFICIENCY_LEVELS[1] }]
|
||||
// }],
|
||||
// });
|
||||
const FormPage: React.FC<FormPageProps> = ({ onFormSubmit }) => {
|
||||
const [formData, setFormData] = useState<FormData>({
|
||||
Hackathon: '',
|
||||
mainTheme: '',
|
||||
tracksStack: [''],
|
||||
students: [{
|
||||
studentName: '',
|
||||
skills: [{ skillName: '', proficiency: PROFICIENCY_LEVELS[1] }]
|
||||
}],
|
||||
});
|
||||
|
||||
// const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
// setFormData({
|
||||
// ...formData,
|
||||
// [event.target.name]: event.target.value,
|
||||
// });
|
||||
// };
|
||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setFormData({
|
||||
...formData,
|
||||
[event.target.name]: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
// const handleTracksChange = (event: React.ChangeEvent<HTMLInputElement>, index: number) => {
|
||||
// const newTracksStack = [...formData.tracksStack];
|
||||
// newTracksStack[index] = event.target.value;
|
||||
const handleTracksChange = (event: React.ChangeEvent<HTMLInputElement>, index: number) => {
|
||||
const newTracksStack = [...formData.tracksStack];
|
||||
newTracksStack[index] = event.target.value;
|
||||
|
||||
// setFormData({
|
||||
// ...formData,
|
||||
// tracksStack: newTracksStack,
|
||||
// });
|
||||
// };
|
||||
setFormData({
|
||||
...formData,
|
||||
tracksStack: newTracksStack,
|
||||
});
|
||||
};
|
||||
|
||||
// const handleAddTracks = () => {
|
||||
// setFormData({
|
||||
// ...formData,
|
||||
// tracksStack: [...formData.tracksStack, ''],
|
||||
// });
|
||||
// };
|
||||
const handleAddTracks = () => {
|
||||
setFormData({
|
||||
...formData,
|
||||
tracksStack: [...formData.tracksStack, ''],
|
||||
});
|
||||
};
|
||||
|
||||
// const handleRemoveTracks = (index: number) => {
|
||||
// const newTracksStack = formData.tracksStack.filter((_, i) => i !== index);
|
||||
// setFormData({
|
||||
// ...formData,
|
||||
// tracksStack: newTracksStack,
|
||||
// });
|
||||
// };
|
||||
const handleRemoveTracks = (index: number) => {
|
||||
const newTracksStack = formData.tracksStack.filter((_, i) => i !== index);
|
||||
setFormData({
|
||||
...formData,
|
||||
tracksStack: newTracksStack,
|
||||
});
|
||||
};
|
||||
|
||||
// const handleStudentNameChange = (e: React.ChangeEvent<HTMLInputElement>, studentIndex: number) => {
|
||||
// const newStudents = [...formData.students];
|
||||
// newStudents[studentIndex].studentName = e.target.value;
|
||||
// setFormData({ ...formData, students: newStudents });
|
||||
// };
|
||||
const handleStudentNameChange = (e: React.ChangeEvent<HTMLInputElement>, studentIndex: number) => {
|
||||
const newStudents = [...formData.students];
|
||||
newStudents[studentIndex].studentName = e.target.value;
|
||||
setFormData({ ...formData, students: newStudents });
|
||||
};
|
||||
|
||||
// const handleAddStudent = () => {
|
||||
// setFormData({
|
||||
// ...formData,
|
||||
// students: [...formData.students, { studentName: '', skills: [{ skillName: '', proficiency: PROFICIENCY_LEVELS[1] }] }]
|
||||
// });
|
||||
// };
|
||||
const handleAddStudent = () => {
|
||||
setFormData({
|
||||
...formData,
|
||||
students: [...formData.students, { studentName: '', skills: [{ skillName: '', proficiency: PROFICIENCY_LEVELS[1] }] }]
|
||||
});
|
||||
};
|
||||
|
||||
// const handleRemoveStudent = (studentIndex: number) => {
|
||||
// const newStudents = formData.students.filter((_, i) => i !== studentIndex);
|
||||
// setFormData({ ...formData, students: newStudents });
|
||||
// };
|
||||
const handleRemoveStudent = (studentIndex: number) => {
|
||||
const newStudents = formData.students.filter((_, i) => i !== studentIndex);
|
||||
setFormData({ ...formData, students: newStudents });
|
||||
};
|
||||
|
||||
// const handleSkillChange = (
|
||||
// e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>,
|
||||
// studentIndex: number,
|
||||
// skillIndex: number
|
||||
// ) => {
|
||||
// const newStudents = [...formData.students];
|
||||
// const targetName = e.target.name;
|
||||
// const targetValue = e.target.value;
|
||||
const handleSkillChange = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>,
|
||||
studentIndex: number,
|
||||
skillIndex: number
|
||||
) => {
|
||||
const newStudents = [...formData.students];
|
||||
const targetName = e.target.name;
|
||||
const targetValue = e.target.value;
|
||||
|
||||
// if (targetName === 'skillName') {
|
||||
// newStudents[studentIndex].skills[skillIndex].skillName = targetValue;
|
||||
// } else if (targetName === 'proficiency') {
|
||||
// newStudents[studentIndex].skills[skillIndex].proficiency = targetValue;
|
||||
// }
|
||||
if (targetName === 'skillName') {
|
||||
newStudents[studentIndex].skills[skillIndex].skillName = targetValue;
|
||||
} else if (targetName === 'proficiency') {
|
||||
newStudents[studentIndex].skills[skillIndex].proficiency = targetValue;
|
||||
}
|
||||
|
||||
// setFormData({ ...formData, students: newStudents });
|
||||
// };
|
||||
setFormData({ ...formData, students: newStudents });
|
||||
};
|
||||
|
||||
// const handleAddSkill = (studentIndex: number) => {
|
||||
// const newStudents = [...formData.students];
|
||||
// newStudents[studentIndex].skills.push({ skillName: '', proficiency: PROFICIENCY_LEVELS[1] });
|
||||
// setFormData({ ...formData, students: newStudents });
|
||||
// };
|
||||
const handleAddSkill = (studentIndex: number) => {
|
||||
const newStudents = [...formData.students];
|
||||
newStudents[studentIndex].skills.push({ skillName: '', proficiency: PROFICIENCY_LEVELS[1] });
|
||||
setFormData({ ...formData, students: newStudents });
|
||||
};
|
||||
|
||||
// const handleRemoveSkill = (studentIndex: number, skillIndex: number) => {
|
||||
// const newStudents = [...formData.students];
|
||||
// newStudents[studentIndex].skills = newStudents[studentIndex].skills.filter((_, i) => i !== skillIndex);
|
||||
// setFormData({ ...formData, students: newStudents });
|
||||
// };
|
||||
const handleRemoveSkill = (studentIndex: number, skillIndex: number) => {
|
||||
const newStudents = [...formData.students];
|
||||
newStudents[studentIndex].skills = newStudents[studentIndex].skills.filter((_, i) => i !== skillIndex);
|
||||
setFormData({ ...formData, students: newStudents });
|
||||
};
|
||||
|
||||
// const handleSubmit = (event: React.FormEvent) => {
|
||||
// event.preventDefault();
|
||||
// onFormSubmit(formData); // Call the prop function with formData
|
||||
// };
|
||||
const handleSubmit = (event: React.FormEvent) => {
|
||||
event.preventDefault();
|
||||
onFormSubmit(formData); // Call the prop function with formData
|
||||
};
|
||||
|
||||
// return (
|
||||
// <div className="min-h-screen bg-gray-50 flex items-start justify-center p-4 sm:p-6 font-inter">
|
||||
// <div className="w-full max-w-2xl bg-white p-8 shadow-2xl rounded-xl mt-8">
|
||||
// <h1 className="text-3xl font-extrabold text-center text-gray-800 mb-8 tracking-tight">
|
||||
// Generate Project Idea
|
||||
// </h1>
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 flex items-start justify-center p-4 sm:p-6 font-inter">
|
||||
<div className="w-full max-w-2xl bg-white p-8 shadow-2xl rounded-xl mt-8">
|
||||
<h1 className="text-3xl font-extrabold text-center text-gray-800 mb-8 tracking-tight">
|
||||
Generate Project Idea
|
||||
</h1>
|
||||
|
||||
// <form className="space-y-8" onSubmit={handleSubmit}>
|
||||
// <div className="space-y-6 border-b pb-6 border-gray-200">
|
||||
// <h2 className="text-xl font-bold text-gray-700">Project Context</h2>
|
||||
// <div>
|
||||
// <label htmlFor="hackathonName" className="block text-sm font-medium text-gray-700 mb-1">
|
||||
// Hackathon Name
|
||||
// </label>
|
||||
// <input
|
||||
// id="hackathonName"
|
||||
// required
|
||||
// type="text"
|
||||
// placeholder="e.g., Google Code Jam"
|
||||
// name="Hackathon"
|
||||
// value={formData.Hackathon}
|
||||
// onChange={handleChange}
|
||||
// className="mt-1 block w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-blue-500 focus:border-blue-500 transition duration-150"
|
||||
// />
|
||||
// </div>
|
||||
<form className="space-y-8" onSubmit={handleSubmit}>
|
||||
<div className="space-y-6 border-b pb-6 border-gray-200">
|
||||
<h2 className="text-xl font-bold text-gray-700">Project Context</h2>
|
||||
<div>
|
||||
<label htmlFor="hackathonName" className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Hackathon Name
|
||||
</label>
|
||||
<input
|
||||
id="hackathonName"
|
||||
required
|
||||
type="text"
|
||||
placeholder="e.g., Google Code Jam"
|
||||
name="Hackathon"
|
||||
value={formData.Hackathon}
|
||||
onChange={handleChange}
|
||||
className="mt-1 block w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-blue-500 focus:border-blue-500 transition duration-150"
|
||||
/>
|
||||
</div>
|
||||
|
||||
// <div>
|
||||
// <label htmlFor="mainTheme" className="block text-sm font-medium text-gray-700 mb-1">
|
||||
// Main Theme
|
||||
// </label>
|
||||
// <input
|
||||
// id="mainTheme"
|
||||
// required
|
||||
// type="text"
|
||||
// placeholder="e.g., Sustainability or AI Ethics"
|
||||
// name="mainTheme"
|
||||
// value={formData.mainTheme}
|
||||
// onChange={handleChange}
|
||||
// className="mt-1 block w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-blue-500 focus:border-blue-500 transition duration-150"
|
||||
// />
|
||||
// </div>
|
||||
// </div>
|
||||
<div>
|
||||
<label htmlFor="mainTheme" className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Main Theme
|
||||
</label>
|
||||
<input
|
||||
id="mainTheme"
|
||||
required
|
||||
type="text"
|
||||
placeholder="e.g., Sustainability or AI Ethics"
|
||||
name="mainTheme"
|
||||
value={formData.mainTheme}
|
||||
onChange={handleChange}
|
||||
className="mt-1 block w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-blue-500 focus:border-blue-500 transition duration-150"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
// <div className="space-y-4 border-b pb-6 border-gray-200">
|
||||
// <label className="block text-xl font-bold text-gray-700">
|
||||
// Tracks Stack
|
||||
// </label>
|
||||
// <div className="space-y-3">
|
||||
// {formData.tracksStack.map((tracks, index) => (
|
||||
// <div key={index} className="flex gap-2 items-center">
|
||||
// <input
|
||||
// type="text"
|
||||
// required
|
||||
// placeholder={`Tracks #${index + 1}`}
|
||||
// name={`tracksStack-${index}`}
|
||||
// value={tracks}
|
||||
// onChange={(e) => handleTracksChange(e, index)}
|
||||
// className="flex-grow px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-green-500 focus:border-green-500 transition duration-150"
|
||||
// />
|
||||
// {formData.tracksStack.length > 1 && (
|
||||
// <button
|
||||
// type="button"
|
||||
// onClick={() => handleRemoveTracks(index)}
|
||||
// className="text-sm px-3 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition duration-150 flex-shrink-0"
|
||||
// aria-label={`Remove tracks ${index + 1}`}
|
||||
// >
|
||||
// Remove
|
||||
// </button>
|
||||
// )}
|
||||
// </div>
|
||||
// ))}
|
||||
// </div>
|
||||
<div className="space-y-4 border-b pb-6 border-gray-200">
|
||||
<label className="block text-xl font-bold text-gray-700">
|
||||
Tracks Stack
|
||||
</label>
|
||||
<div className="space-y-3">
|
||||
{formData.tracksStack.map((tracks, index) => (
|
||||
<div key={index} className="flex gap-2 items-center">
|
||||
<input
|
||||
type="text"
|
||||
required
|
||||
placeholder={`Tracks #${index + 1}`}
|
||||
name={`tracksStack-${index}`}
|
||||
value={tracks}
|
||||
onChange={(e) => handleTracksChange(e, index)}
|
||||
className="flex-grow px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-green-500 focus:border-green-500 transition duration-150"
|
||||
/>
|
||||
{formData.tracksStack.length > 1 && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleRemoveTracks(index)}
|
||||
className="text-sm px-3 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition duration-150 flex-shrink-0"
|
||||
aria-label={`Remove tracks ${index + 1}`}
|
||||
>
|
||||
Remove
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
// <button
|
||||
// type="button"
|
||||
// onClick={handleAddTracks}
|
||||
// className="flex items-center justify-center gap-1 py-2 px-4 border border-transparent rounded-lg shadow-sm text-sm font-medium text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 transition duration-150"
|
||||
// >
|
||||
// <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path></svg>
|
||||
// Add Tracks
|
||||
// </button>
|
||||
// </div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleAddTracks}
|
||||
className="flex items-center justify-center gap-1 py-2 px-4 border border-transparent rounded-lg shadow-sm text-sm font-medium text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 transition duration-150"
|
||||
>
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path></svg>
|
||||
Add Tracks
|
||||
</button>
|
||||
</div>
|
||||
|
||||
// <div className="space-y-4">
|
||||
// <h2 className="text-xl font-bold text-gray-700">Team Members and Skills</h2>
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-xl font-bold text-gray-700">Team Members and Skills</h2>
|
||||
|
||||
// <div className="space-y-6">
|
||||
// {formData.students.map((student, studentIndex) => (
|
||||
// <div key={studentIndex} className="p-4 border-2 border-indigo-200 rounded-lg bg-indigo-50 shadow-inner space-y-4">
|
||||
<div className="space-y-6">
|
||||
{formData.students.map((student, studentIndex) => (
|
||||
<div key={studentIndex} className="p-4 border-2 border-indigo-200 rounded-lg bg-indigo-50 shadow-inner space-y-4">
|
||||
|
||||
// <div className="flex justify-between items-center pb-2 border-b border-indigo-300">
|
||||
// <h4 className="text-lg font-semibold text-indigo-700">Student #{studentIndex + 1}</h4>
|
||||
// {formData.students.length > 1 && (
|
||||
// <button
|
||||
// type="button"
|
||||
// onClick={() => handleRemoveStudent(studentIndex)}
|
||||
// className="text-xs px-2 py-1 bg-red-400 text-white rounded-md hover:bg-red-500 transition duration-150"
|
||||
// >
|
||||
// Remove Student
|
||||
// </button>
|
||||
// )}
|
||||
// </div>
|
||||
<div className="flex justify-between items-center pb-2 border-b border-indigo-300">
|
||||
<h4 className="text-lg font-semibold text-indigo-700">Student #{studentIndex + 1}</h4>
|
||||
{formData.students.length > 1 && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleRemoveStudent(studentIndex)}
|
||||
className="text-xs px-2 py-1 bg-red-400 text-white rounded-md hover:bg-red-500 transition duration-150"
|
||||
>
|
||||
Remove Student
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
// <div>
|
||||
// <label className="block text-sm font-medium text-indigo-700 mb-1">Student Name</label>
|
||||
// <input
|
||||
// type="text"
|
||||
// required
|
||||
// placeholder="Student Name"
|
||||
// value={student.studentName}
|
||||
// onChange={(e) => handleStudentNameChange(e, studentIndex)}
|
||||
// className="w-full px-4 py-2 border border-indigo-300 rounded-lg shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
|
||||
// />
|
||||
// </div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-indigo-700 mb-1">Student Name</label>
|
||||
<input
|
||||
type="text"
|
||||
required
|
||||
placeholder="Student Name"
|
||||
value={student.studentName}
|
||||
onChange={(e) => handleStudentNameChange(e, studentIndex)}
|
||||
className="w-full px-4 py-2 border border-indigo-300 rounded-lg shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
// <div className="space-y-3 p-3 bg-white rounded-lg border border-indigo-100">
|
||||
// <h5 className="text-md font-medium text-indigo-700">Skills</h5>
|
||||
// {student.skills.map((skill, skillIndex) => (
|
||||
// <div key={skillIndex} className="flex gap-2 items-center">
|
||||
// <input
|
||||
// type="text"
|
||||
// required
|
||||
// name="skillName"
|
||||
// placeholder="Skill (e.g., React, Python)"
|
||||
// value={skill.skillName}
|
||||
// onChange={(e) => handleSkillChange(e, studentIndex, skillIndex)}
|
||||
// className="flex-grow px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-purple-500 focus:border-purple-500"
|
||||
// />
|
||||
// <select
|
||||
// name="proficiency"
|
||||
// value={skill.proficiency}
|
||||
// onChange={(e) => handleSkillChange(e, studentIndex, skillIndex)}
|
||||
// className="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-purple-500 focus:border-purple-500 w-1/3"
|
||||
// >
|
||||
// {PROFICIENCY_LEVELS.map(level => (
|
||||
// <option key={level} value={level}>{level}</option>
|
||||
// ))}
|
||||
// </select>
|
||||
// {student.skills.length > 1 && (
|
||||
// <button
|
||||
// type="button"
|
||||
// onClick={() => handleRemoveSkill(studentIndex, skillIndex)}
|
||||
// className="text-xs px-2 py-1 bg-red-500 text-white rounded-md hover:bg-red-600 transition duration-150 flex-shrink-0"
|
||||
// >
|
||||
// X
|
||||
// </button>
|
||||
// )}
|
||||
// </div>
|
||||
// ))}
|
||||
// <button
|
||||
// type="button"
|
||||
// onClick={() => handleAddSkill(studentIndex)}
|
||||
// className="mt-2 text-xs flex items-center gap-1 py-1 px-3 border border-transparent rounded-lg text-white bg-purple-600 hover:bg-purple-700 transition duration-150"
|
||||
// >
|
||||
// + Add Skill
|
||||
// </button>
|
||||
// </div>
|
||||
// </div>
|
||||
// ))}
|
||||
// </div>
|
||||
<div className="space-y-3 p-3 bg-white rounded-lg border border-indigo-100">
|
||||
<h5 className="text-md font-medium text-indigo-700">Skills</h5>
|
||||
{student.skills.map((skill, skillIndex) => (
|
||||
<div key={skillIndex} className="flex gap-2 items-center">
|
||||
<input
|
||||
type="text"
|
||||
required
|
||||
name="skillName"
|
||||
placeholder="Skill (e.g., React, Python)"
|
||||
value={skill.skillName}
|
||||
onChange={(e) => handleSkillChange(e, studentIndex, skillIndex)}
|
||||
className="flex-grow px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-purple-500 focus:border-purple-500"
|
||||
/>
|
||||
<select
|
||||
name="proficiency"
|
||||
value={skill.proficiency}
|
||||
onChange={(e) => handleSkillChange(e, studentIndex, skillIndex)}
|
||||
className="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-purple-500 focus:border-purple-500 w-1/3"
|
||||
>
|
||||
{PROFICIENCY_LEVELS.map(level => (
|
||||
<option key={level} value={level}>{level}</option>
|
||||
))}
|
||||
</select>
|
||||
{student.skills.length > 1 && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleRemoveSkill(studentIndex, skillIndex)}
|
||||
className="text-xs px-2 py-1 bg-red-500 text-white rounded-md hover:bg-red-600 transition duration-150 flex-shrink-0"
|
||||
>
|
||||
X
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleAddSkill(studentIndex)}
|
||||
className="mt-2 text-xs flex items-center gap-1 py-1 px-3 border border-transparent rounded-lg text-white bg-purple-600 hover:bg-purple-700 transition duration-150"
|
||||
>
|
||||
+ Add Skill
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
// <button
|
||||
// type="button"
|
||||
// onClick={handleAddStudent}
|
||||
// className="mt-4 w-full flex items-center justify-center gap-2 py-2 px-4 border border-transparent rounded-lg shadow-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition duration-150"
|
||||
// >
|
||||
// <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z"></path></svg>
|
||||
// Add Team Member
|
||||
// </button>
|
||||
// </div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleAddStudent}
|
||||
className="mt-4 w-full flex items-center justify-center gap-2 py-2 px-4 border border-transparent rounded-lg shadow-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition duration-150"
|
||||
>
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z"></path></svg>
|
||||
Add Team Member
|
||||
</button>
|
||||
</div>
|
||||
|
||||
// <button
|
||||
// type="submit"
|
||||
// className="w-full flex justify-center py-3 px-4 border border-transparent rounded-lg shadow-lg text-lg font-semibold text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition duration-150 mt-6"
|
||||
// >
|
||||
// Generate Idea
|
||||
// </button>
|
||||
// </form>
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full flex justify-center py-3 px-4 border border-transparent rounded-lg shadow-lg text-lg font-semibold text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition duration-150 mt-6"
|
||||
>
|
||||
Generate Idea
|
||||
</button>
|
||||
</form>
|
||||
|
||||
// </div>
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// export default FormPage;
|
||||
export default FormPage;
|
||||
+18
-18
@@ -1,21 +1,21 @@
|
||||
// // Define Skill structure
|
||||
// export interface Skill {
|
||||
// skillName: string;
|
||||
// proficiency: string;
|
||||
// }
|
||||
// Define Skill structure
|
||||
export interface Skill {
|
||||
skillName: string;
|
||||
proficiency: string;
|
||||
}
|
||||
|
||||
// // Define Student structure
|
||||
// export interface Student {
|
||||
// studentName: string;
|
||||
// skills: Skill[];
|
||||
// }
|
||||
// Define Student structure
|
||||
export interface Student {
|
||||
studentName: string;
|
||||
skills: Skill[];
|
||||
}
|
||||
|
||||
// // Updated main form interface
|
||||
// export interface FormData {
|
||||
// Hackathon: string;
|
||||
// mainTheme: string;
|
||||
// tracksStack: string[];
|
||||
// students: Student[]; // Array for dynamic students
|
||||
// }
|
||||
// Updated main form interface
|
||||
export interface FormData {
|
||||
Hackathon: string;
|
||||
mainTheme: string;
|
||||
tracksStack: string[];
|
||||
students: Student[]; // Array for dynamic students
|
||||
}
|
||||
|
||||
// export const PROFICIENCY_LEVELS = ['Beginner', 'Intermediate', 'Expert', 'Master'];
|
||||
export const PROFICIENCY_LEVELS = ['Beginner', 'Intermediate', 'Expert', 'Master'];
|
||||
@@ -1,71 +1,71 @@
|
||||
// import { GoogleGenerativeAI } from "@google/generative-ai";
|
||||
// import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { GoogleGenerativeAI } from "@google/generative-ai";
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
// // Initialize the Gemini Client with your API Key
|
||||
// // IMPORTANT: The GEMINI_API_KEY should be an environment variable.
|
||||
// const apiKey = process.env.GEMINI_API_KEY;
|
||||
// Initialize the Gemini Client with your API Key
|
||||
// IMPORTANT: The GEMINI_API_KEY should be an environment variable.
|
||||
const apiKey = process.env.GEMINI_API_KEY;
|
||||
|
||||
// if(!apiKey){
|
||||
// throw new Error("api key not found");
|
||||
// }
|
||||
// const ai = new GoogleGenerativeAI(apiKey);
|
||||
if (!apiKey) {
|
||||
throw new Error("api key not found");
|
||||
}
|
||||
const ai = new GoogleGenerativeAI(apiKey);
|
||||
|
||||
|
||||
|
||||
// // Define the handler function for the API route
|
||||
// export default async function handler(
|
||||
// req: NextApiRequest,
|
||||
// res: NextApiResponse
|
||||
// ) {
|
||||
// // Only allow POST requests
|
||||
// if (req.method !== 'POST') {
|
||||
// return res.status(405).json({ error: 'Method Not Allowed' });
|
||||
// }
|
||||
// Define the handler function for the API route
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
// Only allow POST requests
|
||||
if (req.method !== 'POST') {
|
||||
return res.status(405).json({ error: 'Method Not Allowed' });
|
||||
}
|
||||
|
||||
// // Destructure the data sent from the frontend
|
||||
// let { prompt, settings } = req.body;
|
||||
|
||||
// // Basic validation
|
||||
// if (!prompt || typeof prompt !== 'string') {
|
||||
// return res.status(400).json({ error: 'Prompt is required' });
|
||||
// }
|
||||
// Destructure the data sent from the frontend
|
||||
let { prompt, settings } = req.body;
|
||||
|
||||
// // Modify the prompt to instruct the AI to generate only the game, concept, and track
|
||||
// prompt = `You're going to fill out a card base off the document.
|
||||
// you will Generate the project short title.
|
||||
// you will list out the track you used ${prompt}`;
|
||||
// Basic validation
|
||||
if (!prompt || typeof prompt !== 'string') {
|
||||
return res.status(400).json({ error: 'Prompt is required' });
|
||||
}
|
||||
|
||||
// try {
|
||||
// // 1. Call the Gemini API using the correct method signature
|
||||
|
||||
// const model = settings?.model || 'gemini-2.5-flash-lite';
|
||||
// const generativeModel = ai.getGenerativeModel({ model });
|
||||
// Modify the prompt to instruct the AI to generate only the game, concept, and track
|
||||
prompt = `You're going to fill out a card base off the document.
|
||||
you will Generate the project short title.
|
||||
you will list out the track you used ${prompt}`;
|
||||
|
||||
// // 1. Define the generation configuration object
|
||||
// const generationConfig = {
|
||||
// temperature: settings?.temperature || 0.9,
|
||||
// // The SDK property name for system instructions is 'systemInstruction'
|
||||
// systemInstruction: settings?.sysTemInstructions,
|
||||
// };
|
||||
try {
|
||||
// 1. Call the Gemini API using the correct method signature
|
||||
|
||||
// // 2. Call generateContent with the single GenerateContentRequest object.
|
||||
// const result = await generativeModel.generateContent({
|
||||
// // contents must be an array of Content objects
|
||||
// contents: [{
|
||||
// role: "user",
|
||||
// parts: [{ text: prompt }]
|
||||
// }],
|
||||
|
||||
// // The fixed property name that resolves the TypeScript error
|
||||
// generationConfig: generationConfig,
|
||||
// });
|
||||
const model = settings?.model || 'gemini-2.5-flash-lite';
|
||||
const generativeModel = ai.getGenerativeModel({ model });
|
||||
|
||||
// // 2. Extract the response text
|
||||
// // The result object now contains a property 'text' at the top level for simple text generation
|
||||
// const geminiResponseText = result.response.text(); res.status(200).json({ response: geminiResponseText });
|
||||
// 1. Define the generation configuration object
|
||||
const generationConfig = {
|
||||
temperature: settings?.temperature || 0.9,
|
||||
// The SDK property name for system instructions is 'systemInstruction'
|
||||
systemInstruction: settings?.sysTemInstructions,
|
||||
};
|
||||
|
||||
// } catch (error) {
|
||||
// console.error("Gemini API Error:", error);
|
||||
// res.status(500).json({ error: 'Failed to generate idea from AI.' });
|
||||
// }
|
||||
// }
|
||||
// 2. Call generateContent with the single GenerateContentRequest object.
|
||||
const result = await generativeModel.generateContent({
|
||||
// contents must be an array of Content objects
|
||||
contents: [{
|
||||
role: "user",
|
||||
parts: [{ text: prompt }]
|
||||
}],
|
||||
|
||||
// The fixed property name that resolves the TypeScript error
|
||||
generationConfig: generationConfig,
|
||||
});
|
||||
|
||||
// 2. Extract the response text
|
||||
// The result object now contains a property 'text' at the top level for simple text generation
|
||||
const geminiResponseText = result.response.text(); res.status(200).json({ response: geminiResponseText });
|
||||
|
||||
} catch (error) {
|
||||
console.error("Gemini API Error:", error);
|
||||
res.status(500).json({ error: 'Failed to generate idea from AI.' });
|
||||
}
|
||||
}
|
||||
|
||||
+159
-159
@@ -1,172 +1,172 @@
|
||||
// "use client";
|
||||
// import React, { useState, useEffect, useCallback } from "react";
|
||||
// import FormPage from './FormPage';
|
||||
// import { ChatSetting } from "../exportType/types";
|
||||
// import { FormData, PROFICIENCY_LEVELS } from './formTypes';
|
||||
"use client";
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import FormPage from './FormPage';
|
||||
import { ChatSetting } from "../exportType/types";
|
||||
import { FormData, PROFICIENCY_LEVELS } from './formTypes';
|
||||
|
||||
// // --- Helper function to get default form data ---
|
||||
// const getDefaultFormData = (): FormData => ({
|
||||
// Hackathon: '',
|
||||
// mainTheme: '',
|
||||
// tracksStack: [''],
|
||||
// students: [{
|
||||
// studentName: '',
|
||||
// skills: [{ skillName: '', proficiency: PROFICIENCY_LEVELS[1] }]
|
||||
// }],
|
||||
// });
|
||||
// --- Helper function to get default form data ---
|
||||
const getDefaultFormData = (): FormData => ({
|
||||
Hackathon: '',
|
||||
mainTheme: '',
|
||||
tracksStack: [''],
|
||||
students: [{
|
||||
studentName: '',
|
||||
skills: [{ skillName: '', proficiency: PROFICIENCY_LEVELS[1] }]
|
||||
}],
|
||||
});
|
||||
|
||||
// // --- New Initializer Function ---
|
||||
// const getInitialState = () => {
|
||||
// if (typeof window === 'undefined') {
|
||||
// return {
|
||||
// data: getDefaultFormData(),
|
||||
// showForm: true,
|
||||
// runEffect: false
|
||||
// };
|
||||
// }
|
||||
// const storedFormData = localStorage.getItem('formData');
|
||||
// if (storedFormData) {
|
||||
// localStorage.removeItem('formData');
|
||||
// return {
|
||||
// data: JSON.parse(storedFormData) as FormData,
|
||||
// showForm: false,
|
||||
// runEffect: true,
|
||||
// };
|
||||
// }
|
||||
// return {
|
||||
// data: getDefaultFormData(),
|
||||
// showForm: true,
|
||||
// runEffect: false
|
||||
// };
|
||||
// };
|
||||
// --- New Initializer Function ---
|
||||
const getInitialState = () => {
|
||||
if (typeof window === 'undefined') {
|
||||
return {
|
||||
data: getDefaultFormData(),
|
||||
showForm: true,
|
||||
runEffect: false
|
||||
};
|
||||
}
|
||||
const storedFormData = localStorage.getItem('formData');
|
||||
if (storedFormData) {
|
||||
localStorage.removeItem('formData');
|
||||
return {
|
||||
data: JSON.parse(storedFormData) as FormData,
|
||||
showForm: false,
|
||||
runEffect: true,
|
||||
};
|
||||
}
|
||||
return {
|
||||
data: getDefaultFormData(),
|
||||
showForm: true,
|
||||
runEffect: false
|
||||
};
|
||||
};
|
||||
|
||||
// // FIX 1 (Memoization): Moved settings OUTSIDE the component.
|
||||
// // This makes it a true constant.
|
||||
// const AI_SETTINGS: ChatSetting = {
|
||||
// temperature: 1,
|
||||
// model: "gemini-2.5-pro",
|
||||
// sysTemInstructions: `You are an elite hackathon idea generator. Your task is to generate five different creative, feasible, and relevant project idea.
|
||||
// The output MUST be in Markdown format and strictly follow this structure:
|
||||
// ### Project Idea Title
|
||||
// **Relevance to Theme:** [Explain briefly]
|
||||
// **Core Technology:** [List 3-5 primary technologies]
|
||||
// **Team Fit:** [How the team's skills apply]
|
||||
// **Concept:** [A concise, single paragraph description of the product and its primary function.]
|
||||
// **Bonus Feature:** [A single, ambitious feature to impress judges.]`,
|
||||
// };
|
||||
// FIX 1 (Memoization): Moved settings OUTSIDE the component.
|
||||
// This makes it a true constant.
|
||||
const AI_SETTINGS: ChatSetting = {
|
||||
temperature: 1,
|
||||
model: "gemini-2.5-pro",
|
||||
sysTemInstructions: `You are an elite hackathon idea generator. Your task is to generate five different creative, feasible, and relevant project idea.
|
||||
The output MUST be in Markdown format and strictly follow this structure:
|
||||
### Project Idea Title
|
||||
**Relevance to Theme:** [Explain briefly]
|
||||
**Core Technology:** [List 3-5 primary technologies]
|
||||
**Team Fit:** [How the team's skills apply]
|
||||
**Concept:** [A concise, single paragraph description of the product and its primary function.]
|
||||
**Bonus Feature:** [A single, ambitious feature to impress judges.]`,
|
||||
};
|
||||
|
||||
// // ------------------------------------------------
|
||||
// ------------------------------------------------
|
||||
|
||||
// export default function Home() {
|
||||
|
||||
// const [initialState] = useState(getInitialState);
|
||||
// const [showForm, setShowForm] = useState(initialState.showForm);
|
||||
// const [formData, setFormData] = useState<FormData>(initialState.data);
|
||||
// const [ideaResponse, setIdeaResponse] = useState<string>("");
|
||||
|
||||
// // The 'settings' state [useState] is now removed from here.
|
||||
export default function Home() {
|
||||
|
||||
// const handleFormSubmitFromFormPage = (submittedData: FormData) => {
|
||||
// setFormData(submittedData);
|
||||
// setShowForm(false);
|
||||
// generateIdeas(submittedData);
|
||||
// };
|
||||
const [initialState] = useState(getInitialState);
|
||||
const [showForm, setShowForm] = useState(initialState.showForm);
|
||||
const [formData, setFormData] = useState<FormData>(initialState.data);
|
||||
const [ideaResponse, setIdeaResponse] = useState<string>("");
|
||||
|
||||
// // Wrapped generateIdeas in useCallback
|
||||
// const generateIdeas = useCallback(async (dataToProcess: FormData) => {
|
||||
// // 1. Data Cleaning
|
||||
// const submissionData: FormData = {
|
||||
// ...dataToProcess,
|
||||
// tracksStack: dataToProcess.tracksStack.filter(tracks => tracks.trim() !== ''),
|
||||
// students: dataToProcess.students
|
||||
// .map(student => ({
|
||||
// ...student,
|
||||
// skills: student.skills.filter(skill => skill.skillName.trim() !== ''),
|
||||
// }))
|
||||
// .filter(student => student.studentName.trim() !== '' || student.skills.length > 0),
|
||||
// };
|
||||
// The 'settings' state [useState] is now removed from here.
|
||||
|
||||
// // 2. Prompt Construction
|
||||
// const prompt = `
|
||||
// Hackathon: ${submissionData.Hackathon}
|
||||
// Main Theme: ${submissionData.mainTheme}
|
||||
// Required Tracks Stack: ${submissionData.tracksStack.join(', ')}
|
||||
// Team Members and Skills: ${submissionData.students.map(s =>
|
||||
// `${s.studentName || 'Unamed Member'} (Skills: ${s.skills.map(sk => `${sk.skillName} - ${sk.proficiency}`).join(', ')})`
|
||||
// ).join('; ')}
|
||||
const handleFormSubmitFromFormPage = (submittedData: FormData) => {
|
||||
setFormData(submittedData);
|
||||
setShowForm(false);
|
||||
generateIdeas(submittedData);
|
||||
};
|
||||
|
||||
// Wrapped generateIdeas in useCallback
|
||||
const generateIdeas = useCallback(async (dataToProcess: FormData) => {
|
||||
// 1. Data Cleaning
|
||||
const submissionData: FormData = {
|
||||
...dataToProcess,
|
||||
tracksStack: dataToProcess.tracksStack.filter(tracks => tracks.trim() !== ''),
|
||||
students: dataToProcess.students
|
||||
.map(student => ({
|
||||
...student,
|
||||
skills: student.skills.filter(skill => skill.skillName.trim() !== ''),
|
||||
}))
|
||||
.filter(student => student.studentName.trim() !== '' || student.skills.length > 0),
|
||||
};
|
||||
|
||||
// 2. Prompt Construction
|
||||
const prompt = `
|
||||
Hackathon: ${submissionData.Hackathon}
|
||||
Main Theme: ${submissionData.mainTheme}
|
||||
Required Tracks Stack: ${submissionData.tracksStack.join(', ')}
|
||||
Team Members and Skills: ${submissionData.students.map(s =>
|
||||
`${s.studentName || 'Unamed Member'} (Skills: ${s.skills.map(sk => `${sk.skillName} - ${sk.proficiency}`).join(', ')})`
|
||||
).join('; ')}
|
||||
|
||||
// Using the SYSTEM INSTRUCTIONS, generate 5 project ideas based on the data above.`;
|
||||
Using the SYSTEM INSTRUCTIONS, generate 5 project ideas based on the data above.`;
|
||||
|
||||
// // 3. API Call
|
||||
// try {
|
||||
// setIdeaResponse("Generating ideas... Please wait.");
|
||||
|
||||
// const response = await fetch("/api/generate-idea", {
|
||||
// method: "POST",
|
||||
// headers: { "Content-Type": "application/json" },
|
||||
// body: JSON.stringify({
|
||||
// prompt: prompt,
|
||||
// settings: AI_SETTINGS, // Use the constant
|
||||
// }),
|
||||
// });
|
||||
// 3. API Call
|
||||
try {
|
||||
setIdeaResponse("Generating ideas... Please wait.");
|
||||
|
||||
// const data = await response.json();
|
||||
// if (data.error || !response.ok) {
|
||||
// console.error("AI Error:", data.error);
|
||||
// setIdeaResponse(`Error: Failed to generate idea. ${data.error || response.statusText}`);
|
||||
// return;
|
||||
// }
|
||||
// setIdeaResponse(data.response);
|
||||
|
||||
// // FIX 2 (Unexpected any): Changed 'any' to 'unknown' and added a type check.
|
||||
// } catch (error: unknown) {
|
||||
// console.error("Request Failed:", error);
|
||||
// let errorMessage = "A network error occurred. Please try again.";
|
||||
// if (error instanceof Error) {
|
||||
// errorMessage += ` Details: ${error.message}`;
|
||||
// }
|
||||
// setIdeaResponse(errorMessage);
|
||||
// }
|
||||
// // FIX 3 (Linter): Disable the faulty memoization rule.
|
||||
// // The empty array is correct because setIdeaResponse is a stable state setter.
|
||||
// // eslint-disable-next-line react-hooks/preserve-manual-memoization
|
||||
// }, []);
|
||||
const response = await fetch("/api/generate-idea", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
prompt: prompt,
|
||||
settings: AI_SETTINGS, // Use the constant
|
||||
}),
|
||||
});
|
||||
|
||||
// // Replaced useEffect
|
||||
// useEffect(() => {
|
||||
// if (initialState.runEffect) {
|
||||
// generateIdeas(initialState.data);
|
||||
// }
|
||||
// }, [initialState, generateIdeas]);
|
||||
const data = await response.json();
|
||||
if (data.error || !response.ok) {
|
||||
console.error("AI Error:", data.error);
|
||||
setIdeaResponse(`Error: Failed to generate idea. ${data.error || response.statusText}`);
|
||||
return;
|
||||
}
|
||||
setIdeaResponse(data.response);
|
||||
|
||||
// // --- JSX Rendering ---
|
||||
// return (
|
||||
// <main className="min-h-screen bg-gray-50 flex items-start justify-center p-4 sm:p-6 font-inter">
|
||||
// <div className="w-full max-w-2xl bg-white p-8 shadow-2xl rounded-xl mt-8">
|
||||
// {showForm ? (
|
||||
// <FormPage onFormSubmit={handleFormSubmitFromFormPage} />
|
||||
// ) : (
|
||||
// <>
|
||||
// <h1 className="text-3xl font-extrabold text-center text-gray-800 mb-8 tracking-tight">
|
||||
// Generated Project Idea 💡
|
||||
// </h1>
|
||||
// <div className="mt-8 p-4 bg-yellow-50 rounded-lg border border-yellow-200">
|
||||
// <h2 className="text-xl font-bold text-gray-700 mb-2">Generated Ideas:</h2>
|
||||
// <div
|
||||
// className="prose max-w-none"
|
||||
// dangerouslySetInnerHTML={{ __html: ideaResponse.replace(/\n/g, '<br/>') }}
|
||||
// />
|
||||
// {ideaResponse === "" && <p className="text-gray-500">Submit the form to generate project ideas.</p>}
|
||||
// </div>
|
||||
// <button
|
||||
// onClick={() => setShowForm(true)}
|
||||
// className="mt-6 w-full flex justify-center py-3 px-4 border border-transparent rounded-lg shadow-lg text-lg font-semibold text-white bg-blue-600 hover:bg-blue-700 transition duration-150"
|
||||
// >
|
||||
// Go Back to Form
|
||||
// </button>
|
||||
// </>
|
||||
// )}
|
||||
// </div>
|
||||
// </main>
|
||||
// );
|
||||
// }
|
||||
// FIX 2 (Unexpected any): Changed 'any' to 'unknown' and added a type check.
|
||||
} catch (error: unknown) {
|
||||
console.error("Request Failed:", error);
|
||||
let errorMessage = "A network error occurred. Please try again.";
|
||||
if (error instanceof Error) {
|
||||
errorMessage += ` Details: ${error.message}`;
|
||||
}
|
||||
setIdeaResponse(errorMessage);
|
||||
}
|
||||
// FIX 3 (Linter): Disable the faulty memoization rule.
|
||||
// The empty array is correct because setIdeaResponse is a stable state setter.
|
||||
// eslint-disable-next-line react-hooks/preserve-manual-memoization
|
||||
}, []);
|
||||
|
||||
// Replaced useEffect
|
||||
useEffect(() => {
|
||||
if (initialState.runEffect) {
|
||||
generateIdeas(initialState.data);
|
||||
}
|
||||
}, [initialState, generateIdeas]);
|
||||
|
||||
// --- JSX Rendering ---
|
||||
return (
|
||||
<main className="min-h-screen bg-gray-50 flex items-start justify-center p-4 sm:p-6 font-inter">
|
||||
<div className="w-full max-w-2xl bg-white p-8 shadow-2xl rounded-xl mt-8">
|
||||
{showForm ? (
|
||||
<FormPage onFormSubmit={handleFormSubmitFromFormPage} />
|
||||
) : (
|
||||
<>
|
||||
<h1 className="text-3xl font-extrabold text-center text-gray-800 mb-8 tracking-tight">
|
||||
Generated Project Idea 💡
|
||||
</h1>
|
||||
<div className="mt-8 p-4 bg-yellow-50 rounded-lg border border-yellow-200">
|
||||
<h2 className="text-xl font-bold text-gray-700 mb-2">Generated Ideas:</h2>
|
||||
<div
|
||||
className="prose max-w-none"
|
||||
dangerouslySetInnerHTML={{ __html: ideaResponse.replace(/\n/g, '<br/>') }}
|
||||
/>
|
||||
{ideaResponse === "" && <p className="text-gray-500">Submit the form to generate project ideas.</p>}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setShowForm(true)}
|
||||
className="mt-6 w-full flex justify-center py-3 px-4 border border-transparent rounded-lg shadow-lg text-lg font-semibold text-white bg-blue-600 hover:bg-blue-700 transition duration-150"
|
||||
>
|
||||
Go Back to Form
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user