Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Zodiac Event Wizard</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script> | |
| <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script> | |
| <script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/index.min.js"></script> | |
| <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> | |
| <style> | |
| .bg-primary { | |
| background-color: #6366f1; | |
| } | |
| .bg-secondary { | |
| background-color: #10b981; | |
| } | |
| .text-primary { | |
| color: #6366f1; | |
| } | |
| .text-secondary { | |
| color: #10b981; | |
| } | |
| .border-primary { | |
| border-color: #6366f1; | |
| } | |
| .border-secondary { | |
| border-color: #10b981; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 min-h-screen"> | |
| <div id="root"></div> | |
| <script type="text/babel"> | |
| const { useState } = React; | |
| const EventForm = () => { | |
| const [step, setStep] = useState(1); | |
| const [loading, setLoading] = useState(false); | |
| const [success, setSuccess] = useState(false); | |
| const [formData, setFormData] = useState({ | |
| name: '', | |
| date: '', | |
| time: '', | |
| description: '', | |
| category: '', | |
| privacy: 'public', | |
| reminders: false | |
| }); | |
| const nextStep = () => setStep(prev => Math.min(prev + 1, 4)); | |
| const prevStep = () => setStep(prev => Math.max(prev - 1, 1)); | |
| const handleChange = (e) => { | |
| const { name, value, type, checked } = e.target; | |
| setFormData(prev => ({ | |
| ...prev, | |
| [name]: type === 'checkbox' ? checked : value | |
| })); | |
| }; | |
| const handleSubmit = (e) => { | |
| e.preventDefault(); | |
| setLoading(true); | |
| // Simulate API call | |
| setTimeout(() => { | |
| setLoading(false); | |
| setSuccess(true); | |
| }, 1500); | |
| }; | |
| if (success) { | |
| return ( | |
| <div className="max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl p-8 text-center"> | |
| <div className="h-20 w-20 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-6"> | |
| <i data-feather="check" className="text-green-500 w-12 h-12"></i> | |
| </div> | |
| <h2 className="text-2xl font-bold text-gray-800 mb-2">Event Created Successfully!</h2> | |
| <p className="text-gray-600 mb-6">Your event has been scheduled successfully.</p> | |
| <button | |
| onClick={() => { | |
| setSuccess(false); | |
| setStep(1); | |
| setFormData({ | |
| name: '', | |
| date: '', | |
| time: '', | |
| description: '', | |
| category: '', | |
| privacy: 'public', | |
| reminders: false | |
| }); | |
| }} | |
| className="bg-primary hover:bg-indigo-600 text-white font-medium py-2 px-6 rounded-full transition duration-300" | |
| > | |
| Create Another Event | |
| </button> | |
| </div> | |
| ); | |
| } | |
| return ( | |
| <div className="max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl my-8"> | |
| <div className="p-8"> | |
| <div className="flex justify-between items-center mb-8"> | |
| {[1, 2, 3, 4].map((i) => ( | |
| <div key={i} className="flex flex-col items-center"> | |
| <div className={`h-10 w-10 rounded-full flex items-center justify-center ${i <= step ? 'bg-primary text-white' : 'bg-gray-200 text-gray-600'}`}> | |
| {i} | |
| </div> | |
| <span className={`text-xs mt-2 ${i <= step ? 'text-primary font-medium' : 'text-gray-500'}`}> | |
| {i === 1 ? 'Details' : i === 2 ? 'Description' : i === 3 ? 'Settings' : 'Review'} | |
| </span> | |
| </div> | |
| ))} | |
| </div> | |
| <form onSubmit={handleSubmit}> | |
| {/* Step 1 */} | |
| {step === 1 && ( | |
| <div className="space-y-6"> | |
| <h2 className="text-2xl font-bold text-gray-800">Event Details</h2> | |
| <div> | |
| <label className="block text-gray-700 text-sm font-medium mb-1">Event Name</label> | |
| <input | |
| type="text" | |
| name="name" | |
| value={formData.name} | |
| onChange={handleChange} | |
| className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary" | |
| required | |
| /> | |
| </div> | |
| <div className="grid grid-cols-2 gap-4"> | |
| <div> | |
| <label className="block text-gray-700 text-sm font-medium mb-1">Date</label> | |
| <input | |
| type="date" | |
| name="date" | |
| value={formData.date} | |
| onChange={handleChange} | |
| className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary" | |
| required | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-gray-700 text-sm font-medium mb-1">Time</label> | |
| <input | |
| type="time" | |
| name="time" | |
| value={formData.time} | |
| onChange={handleChange} | |
| className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary" | |
| required | |
| /> | |
| </div> | |
| </div> | |
| </div> | |
| )} | |
| {/* Step 2 */} | |
| {step === 2 && ( | |
| <div className="space-y-6"> | |
| <h2 className="text-2xl font-bold text-gray-800">Description</h2> | |
| <div> | |
| <label className="block text-gray-700 text-sm font-medium mb-1">Description</label> | |
| <textarea | |
| name="description" | |
| value={formData.description} | |
| onChange={handleChange} | |
| rows="4" | |
| className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary" | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-gray-700 text-sm font-medium mb-1">Category</label> | |
| <select | |
| name="category" | |
| value={formData.category} | |
| onChange={handleChange} | |
| className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary" | |
| required | |
| > | |
| <option value="">Select a category</option> | |
| <option value="business">Business</option> | |
| <option value="social">Social</option> | |
| <option value="education">Education</option> | |
| <option value="entertainment">Entertainment</option> | |
| </select> | |
| </div> | |
| </div> | |
| )} | |
| {/* Step 3 */} | |
| {step === 3 && ( | |
| <div className="space-y-6"> | |
| <h2 className="text-2xl font-bold text-gray-800">Settings</h2> | |
| <div> | |
| <label className="block text-gray-700 text-sm font-medium mb-1">Privacy</label> | |
| <div className="space-y-2"> | |
| <label className="flex items-center space-x-2"> | |
| <input | |
| type="radio" | |
| name="privacy" | |
| value="public" | |
| checked={formData.privacy === 'public'} | |
| onChange={handleChange} | |
| className="text-primary" | |
| /> | |
| <span>Public (Anyone can see)</span> | |
| </label> | |
| <label className="flex items-center space-x-2"> | |
| <input | |
| type="radio" | |
| name="privacy" | |
| value="private" | |
| checked={formData.privacy === 'private'} | |
| onChange={handleChange} | |
| className="text-primary" | |
| /> | |
| <span>Private (Invite only)</span> | |
| </label> | |
| </div> | |
| </div> | |
| <div> | |
| <label className="flex items-center space-x-2"> | |
| <input | |
| type="checkbox" | |
| name="reminders" | |
| checked={formData.reminders} | |
| onChange={handleChange} | |
| className="text-primary rounded" | |
| /> | |
| <span>Send reminder notifications</span> | |
| </label> | |
| </div> | |
| </div> | |
| )} | |
| {/* Step 4 */} | |
| {step === 4 && ( | |
| <div className="space-y-6"> | |
| <h2 className="text-2xl font-bold text-gray-800">Review</h2> | |
| <div className="bg-gray-50 p-4 rounded-lg"> | |
| <div className="grid grid-cols-2 gap-4 mb-4"> | |
| <div> | |
| <p className="text-sm text-gray-500">Event Name</p> | |
| <p className="font-medium">{formData.name}</p> | |
| </div> | |
| <div> | |
| <p className="text-sm text-gray-500">Date & Time</p> | |
| <p className="font-medium">{formData.date} at {formData.time}</p> | |
| </div> | |
| </div> | |
| <div className="mb-4"> | |
| <p className="text-sm text-gray-500">Description</p> | |
| <p className="font-medium">{formData.description || 'No description'}</p> | |
| </div> | |
| <div className="grid grid-cols-2 gap-4"> | |
| <div> | |
| <p className="text-sm text-gray-500">Category</p> | |
| <p className="font-medium">{formData.category || 'Not selected'}</p> | |
| </div> | |
| <div> | |
| <p className="text-sm text-gray-500">Privacy</p> | |
| <p className="font-medium capitalize">{formData.privacy}</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| )} | |
| <div className="mt-8 flex justify-between"> | |
| {step > 1 && ( | |
| <button | |
| type="button" | |
| onClick={prevStep} | |
| className="px-6 py-2 border border-gray-300 rounded-full text-gray-700 hover:bg-gray-100 transition duration-300" | |
| > | |
| Previous | |
| </button> | |
| )} | |
| {step < 4 ? ( | |
| <button | |
| type="button" | |
| onClick={nextStep} | |
| className="ml-auto bg-primary hover:bg-indigo-600 text-white font-medium py-2 px-6 rounded-full transition duration-300" | |
| > | |
| Next | |
| </button> | |
| ) : ( | |
| <button | |
| type="submit" | |
| disabled={loading} | |
| className="ml-auto bg-primary hover:bg-indigo-600 text-white font-medium py-2 px-6 rounded-full transition duration-300 flex items-center" | |
| > | |
| {loading ? ( | |
| <> | |
| <svg className="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"> | |
| <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle> | |
| <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> | |
| </svg> | |
| Submitting... | |
| </> | |
| ) : 'Submit'} | |
| </button> | |
| )} | |
| </div> | |
| </form> | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| const App = () => { | |
| return ( | |
| <div className="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 py-12 px-4 sm:px-6 lg:px-8"> | |
| <div className="text-center mb-10"> | |
| <div className="flex justify-center mb-4"> | |
| <div className="h-16 w-16 bg-primary rounded-full flex items-center justify-center"> | |
| <i data-feather="calendar" className="text-white w-8 h-8"></i> | |
| </div> | |
| </div> | |
| <h1 className="text-3xl font-bold text-gray-900 mb-2">Zodiac Event Wizard</h1> | |
| <p className="text-gray-600">Create your perfect event in just a few steps</p> | |
| </div> | |
| <EventForm /> | |
| </div> | |
| ); | |
| }; | |
| ReactDOM.render(<App />, document.getElementById('root')); | |
| feather.replace(); | |
| </script> | |
| </body> | |
| </html> | |