Mission Page: Button sets Editable Inputs
Let's now set up to edit the Mission title and description. We're going to expand the editable content to include inputs representing the title and description.
But first, we setup new state variables title
and description
from useState
hooks. We initialize with the mission
variables. We setup change functions to setTitle
/ setDescriptions
from inputs.
In the editing content, we're rendering a lot more now. In the MissionTitleRow
, we're rendering an input for the title, and two new buttons (Update / Cancel). Update is going to simply call a new function saveMission
that just sets editing to false. Cancel will also set editing to false, but will revert to the original variables (note, saving doesn't persist, so canceling will revert to the original mission). We'll modify the saveMission
more in the next module.
To edit the description, we use a new TextArea component imported from the Input.js
file.
import { useState, useMemo } from "react"; import styled from "styled-components"; import { useParams } from "react-router-dom"; import { missions } from "./Missions"; import Button from "../Components/Button"; import Input from "../Components/Input"; import { TextArea } from "../Components/Input"; const MissionTitleRow = styled.div` display: grid; grid-template-columns: 1fr 200px; `; const MissionTitle = styled.h2` font-size: 32px; `; const DescriptionContainer = styled.div``; const EditDescriptionContainer = styled.div``; const DescriptionParagraph = styled.p` font-size: 22px; font-weight: normal; line-height: 21px; `; const MissionActions = styled.div` display: grid; grid-auto-flow: column; justify-self: right; gap: 4px; `; function findMissionById(id) { return () => missions.find((mission) => mission.id == id); } function Mission() { const { id } = useParams(); const mission = useMemo(findMissionById(id), []); const [editing, setEditing] = useState(false); const [title, setTitle] = useState(mission?.title); const [description, setDescription] = useState(mission?.description); if (!mission) { return <div> No mission found </div>; } const onChangeTitle = ({ target: { value } }) => setTitle(value); const onChangeDescription = ({ target: { value } }) => setDescription(value); function saveMission() { setEditing(false); } function revert() { setEditing(false); setTitle(mission?.title); setDescription(mission?.description); } return editing ? ( <> <MissionTitleRow> <Input placeholder="Mission Title" autoFocus value={title} onChange={onChangeTitle} /> <div> <Button onClick={saveMission}> Update </Button> <Button variant="outline" onClick={revert}> {" "} Cancel{" "} </Button> </div> </MissionTitleRow> <EditDescriptionContainer> <TextArea placeholder="Description" size="small" value={description} onChange={onChangeDescription} /> </EditDescriptionContainer> </> ) : ( <div> <MissionTitleRow> <MissionTitle> {title} </MissionTitle> <MissionActions> <Button variant="outline" onClick={() => setEditing(true)}> Edit </Button> <Button variant="outline">Delete</Button> </MissionActions> </MissionTitleRow> <DescriptionContainer> <DescriptionParagraph>{description}</DescriptionParagraph> </DescriptionContainer> </div> ); } export default Mission;