Spaces:
Running
Running
| const App = () => { | |
| const [parties, setParties] = React.useState([ | |
| { | |
| id: 1, | |
| title: "Beach Bonanza", | |
| date: "2023-07-15", | |
| location: "Santa Monica Beach", | |
| host: "Alex Johnson", | |
| attendees: 12, | |
| items: ["Cooler", "Beach Towels", "Snacks", "Sunscreen"] | |
| }, | |
| { | |
| id: 2, | |
| title: "Housewarming Party", | |
| date: "2023-08-02", | |
| location: "123 Main St", | |
| host: "Jamie Smith", | |
| attendees: 25, | |
| items: ["Appetizers", "Drinks", "Dessert", "Games"] | |
| } | |
| ]); | |
| const [activeTab, setActiveTab] = React.useState('create'); | |
| const createNewParty = (e) => { | |
| e.preventDefault(); | |
| const form = e.target; | |
| const newParty = { | |
| id: parties.length + 1, | |
| title: form.title.value, | |
| date: form.date.value, | |
| location: form.location.value, | |
| host: "You", | |
| attendees: 0, | |
| items: form.items.value.split(',').map(item => item.trim()) | |
| }; | |
| setParties([...parties, newParty]); | |
| form.reset(); | |
| setActiveTab('view'); | |
| }; | |
| return ( | |
| <div className="space-y-8"> | |
| <div className="text-center"> | |
| <h1 className="text-4xl font-bold text-purple-800 mb-2">Party Planner Pro</h1> | |
| <p className="text-lg text-purple-600">Plan your perfect party and coordinate with friends!</p> | |
| </div> | |
| <div className="flex justify-center gap-4 mb-8"> | |
| <button | |
| onClick={() => setActiveTab('create')} | |
| className={`px-6 py-2 rounded-full font-medium ${activeTab === 'create' ? 'bg-purple-600 text-white' : 'bg-white text-purple-600 border border-purple-300'}`} | |
| > | |
| Create Party | |
| </button> | |
| <button | |
| onClick={() => setActiveTab('view')} | |
| className={`px-6 py-2 rounded-full font-medium ${activeTab === 'view' ? 'bg-purple-600 text-white' : 'bg-white text-purple-600 border border-purple-300'}`} | |
| > | |
| View Parties | |
| </button> | |
| </div> | |
| {activeTab === 'create' ? ( | |
| <div className="max-w-2xl mx-auto bg-white rounded-xl shadow-md overflow-hidden p-6"> | |
| <h2 className="text-2xl font-bold text-purple-800 mb-6">Create New Party</h2> | |
| <form onSubmit={createNewParty} className="space-y-4"> | |
| <div> | |
| <label className="block text-purple-700 mb-1">Party Title</label> | |
| <input | |
| type="text" | |
| name="title" | |
| required | |
| className="w-full px-4 py-2 border border-purple-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500" | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-purple-700 mb-1">Date</label> | |
| <input | |
| type="date" | |
| name="date" | |
| required | |
| className="w-full px-4 py-2 border border-purple-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500" | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-purple-700 mb-1">Location</label> | |
| <input | |
| type="text" | |
| name="location" | |
| required | |
| className="w-full px-4 py-2 border border-purple-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500" | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-purple-700 mb-1">Items Needed (comma separated)</label> | |
| <textarea | |
| name="items" | |
| placeholder="e.g., Drinks, Snacks, Plates, Cups" | |
| className="w-full px-4 py-2 border border-purple-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500" | |
| ></textarea> | |
| </div> | |
| <button | |
| type="submit" | |
| className="w-full bg-purple-600 hover:bg-purple-700 text-white font-bold py-3 px-4 rounded-lg transition duration-200" | |
| > | |
| Create Party | |
| </button> | |
| </form> | |
| </div> | |
| ) : ( | |
| <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> | |
| {parties.map(party => ( | |
| <div key={party.id} className="party-card bg-white rounded-xl shadow-md overflow-hidden"> | |
| <div className="p-6"> | |
| <div className="flex justify-between items-start mb-2"> | |
| <h3 className="text-xl font-bold text-purple-800">{party.title}</h3> | |
| <span className="bg-purple-100 text-purple-800 text-xs font-medium px-2.5 py-0.5 rounded-full"> | |
| {party.attendees} attending | |
| </span> | |
| </div> | |
| <p className="text-gray-600 mb-4"> | |
| <i data-feather="calendar" className="inline mr-2 w-4 h-4"></i> | |
| {new Date(party.date).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })} | |
| </p> | |
| <p className="text-gray-600 mb-4"> | |
| <i data-feather="map-pin" className="inline mr-2 w-4 h-4"></i> | |
| {party.location} | |
| </p> | |
| <p className="text-gray-600 mb-4"> | |
| <i data-feather="user" className="inline mr-2 w-4 h-4"></i> | |
| Hosted by {party.host} | |
| </p> | |
| <div className="mb-4"> | |
| <h4 className="font-medium text-purple-700 mb-2">Items to bring:</h4> | |
| <ul className="space-y-2"> | |
| {party.items.map((item, index) => ( | |
| <li key={index} className="flex items-center"> | |
| <input type="checkbox" id={`item-${party.id}-${index}`} className="mr-2"/> | |
| <label htmlFor={`item-${party.id}-${index}`}>{item}</label> | |
| </li> | |
| ))} | |
| </ul> | |
| </div> | |
| <div className="flex justify-between mt-6"> | |
| <button className="text-purple-600 hover:text-purple-800 font-medium flex items-center"> | |
| <i data-feather="share-2" className="mr-2 w-4 h-4"></i> | |
| Share | |
| </button> | |
| <button className="bg-purple-600 hover:bg-purple-700 text-white font-medium py-2 px-4 rounded-lg transition duration-200"> | |
| Join Party | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| }; | |
| ReactDOM.createRoot(document.getElementById('root')).render(<App />); |