Last active
April 28, 2023 01:35
-
-
Save pkellner/892f588238847bbfab00aadcdca901e7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect, useState } from "react"; | |
const CHARS = new Set(" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); | |
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); | |
function isAlphanumeric(char) { | |
return CHARS.has(char); | |
} | |
const CookieEditor = () => { | |
const [cookies, setCookies] = useState([]); | |
const [editIndex, setEditIndex] = useState(null); | |
const [inputValue, setInputValue] = useState(""); | |
const fetchCookies = async () => { | |
await sleep(1000); | |
return [ | |
{ id: 1, name: "Chocolate Chip" }, | |
{ id: 2, name: "Oatmeal Raisin" }, | |
{ id: 3, name: "Peanut Butter" }, | |
]; | |
}; | |
useEffect(() => { | |
const loadCookies = async () => { | |
const fetchedCookies = await fetchCookies(); | |
setCookies(fetchedCookies); | |
}; | |
loadCookies().then(() => {}); | |
}, []); | |
const handleChange = (e) => { | |
setInputValue(e.target.value); | |
}; | |
const handleEdit = (index) => { | |
setEditIndex(index); | |
setInputValue(cookies[index].name); | |
}; | |
const handleUpdate = () => { | |
if (isValidCookieName(inputValue)) { | |
const newCookies = [...cookies]; | |
newCookies[editIndex].name = inputValue; | |
setCookies(newCookies); | |
setEditIndex(null); | |
} else { | |
alert("Cookie name must contain only letters."); | |
} | |
}; | |
const isValidCookieName = (name) => { | |
return name.split("").every((char) => isAlphanumeric(char)); | |
}; | |
return ( | |
<div> | |
<h1>Delicious Cookie Editor</h1> | |
<ul> | |
{cookies.map((cookie, index) => ( | |
<li key={cookie.id}> | |
{editIndex === index ? ( | |
<input | |
type="text" | |
value={inputValue} | |
onChange={(e) => handleChange(e)} | |
/> | |
) : ( | |
<span>{cookie.name}</span> | |
)} | |
{editIndex === index ? ( | |
<button | |
onClick={handleUpdate} | |
disabled={!isValidCookieName(inputValue)} | |
> | |
Update | |
</button> | |
) : ( | |
<button onClick={() => handleEdit(index)}>Edit</button> | |
)} | |
</li> | |
))} | |
</ul> | |
</div> | |
); | |
}; | |
function MainContent() { | |
const [i, setI] = useState(0); | |
function incrementBy2() { | |
setI(i+2); | |
} | |
return ( | |
<div> | |
<div> | |
<button | |
onClick={() => { | |
incrementBy2(); | |
incrementBy2(); | |
}} | |
> | |
Increment by 4 (incrementBy2 called twice) | |
</button>{" "} | |
{i} | |
</div> | |
<CookieEditor /> | |
</div> | |
); | |
} | |
function TopOfPage({ | |
eventName, | |
eventDate, | |
eventRegistrationOpen, | |
numberSpeakers, | |
currentDateTime, | |
}) { | |
const [currentDate, setCurrentDate] = useState(new Date(currentDateTime)); | |
useEffect(() => { | |
const interval = setInterval(() => { | |
setCurrentDate((oldDate) => new Date(oldDate.getTime() + 1000)); | |
}, 1000); | |
}, []); | |
return ( | |
<> | |
<div | |
style={{ | |
display: "flex", | |
justifyContent: "space-between", | |
alignItems: "center", | |
}} | |
> | |
<div>{eventName}</div> | |
<div> | |
Event Registration: | |
{new Date(eventRegistrationOpen).toLocaleDateString()} | |
</div> | |
<div>Event Date:{new Date(eventDate).toLocaleDateString()}</div> | |
<div>Current Time: {currentDate.toLocaleDateString()}</div> | |
</div> | |
<div>Speakers: {numberSpeakers}</div> | |
<hr /> | |
</> | |
); | |
} | |
function BottomOfPage() { | |
return ( | |
<div> | |
<hr /> | |
Copyright 2023 | |
</div> | |
); | |
} | |
function AboutContent() { | |
return <h2>This conference is all about delicious cookies!</h2>; | |
} | |
function Nav({ setActivePage }) { | |
return ( | |
<> | |
<div> | |
<button onClick={() => setActivePage("home")}>Home</button> | |
<button onClick={() => setActivePage("about")}>About</button> | |
</div> | |
<hr /> | |
</> | |
); | |
} | |
export default function App() { | |
const eventName = "Cookie Conference"; | |
const eventDate = "2023-11-01T00:00:00.000Z"; | |
const eventRegistrationOpen = "2023-09-01T00:00:00.000Z"; | |
const currentDateTime = new Date().toISOString(); | |
const numberSpeakers = 35; | |
const [activePage, setActivePage] = useState("home"); // valid values: home, about | |
if (activePage === "home") { | |
return ( | |
<div> | |
<TopOfPage | |
eventName={eventName} | |
eventDate={eventDate} | |
eventRegistrationOpen={eventRegistrationOpen} | |
numberSpeakers={numberSpeakers} | |
/> | |
<Nav setActivePage={setActivePage} /> | |
<MainContent /> | |
<BottomOfPage /> | |
</div> | |
); | |
} else if (activePage === "about") { | |
return ( | |
<div> | |
<TopOfPage | |
eventName={eventName} | |
eventDate={eventDate} | |
eventRegistrationOpen={eventRegistrationOpen} | |
numberSpeakers={numberSpeakers} | |
currentDateTime={currentDateTime} | |
/> | |
<Nav setActivePage={setActivePage} /> | |
<AboutContent /> | |
<BottomOfPage /> | |
</div> | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment