diff options
author | Galen Guyer <galen@galenguyer.com> | 2022-08-31 14:09:52 -0400 |
---|---|---|
committer | Galen Guyer <galen@galenguyer.com> | 2022-08-31 14:09:52 -0400 |
commit | 641bcfe174daf231209acc2ecee1dfa681471089 (patch) | |
tree | 9f1ffc6841b18672f7189c90fa43117da6cae980 | |
parent | 4dc20b3e1a90eefd22354f69e058d14a56364689 (diff) |
Add creation of new records in a zone
-rw-r--r-- | src/components/IconButton.js | 4 | ||||
-rw-r--r-- | src/components/Record.js | 14 | ||||
-rw-r--r-- | src/components/RecordModal.js | 14 | ||||
-rw-r--r-- | src/components/RecordTable.js | 10 | ||||
-rw-r--r-- | src/index.js | 3 | ||||
-rw-r--r-- | src/routes/Home.js | 14 | ||||
-rw-r--r-- | src/routes/Records.css | 4 | ||||
-rw-r--r-- | src/routes/Records.js | 61 | ||||
-rw-r--r-- | src/uikit/Input.js | 11 |
9 files changed, 102 insertions, 33 deletions
diff --git a/src/components/IconButton.js b/src/components/IconButton.js index 4757f9a..63f087e 100644 --- a/src/components/IconButton.js +++ b/src/components/IconButton.js @@ -1,11 +1,11 @@ import { styled } from "@stitches/react"; -export default function IconButton({ icon, action }) { +export default function IconButton({ icon, action, children }) { const UnstyledButton = styled("button", { "background-color": "initial", border: "none", "padding-top": "3px", }); - return <UnstyledButton onClick={() => action()}>{icon}</UnstyledButton>; + return <UnstyledButton onClick={() => action()}>{children}</UnstyledButton>; } diff --git a/src/components/Record.js b/src/components/Record.js index 5dcb4d1..e98128a 100644 --- a/src/components/Record.js +++ b/src/components/Record.js @@ -12,14 +12,12 @@ export default function Record(props) { </div> <div class="records-td records-col-ttl">{props.ttl}</div> <div class="records-td records-col-actions"> - <IconButton - icon="pencil" - action={() => props.setAndOpenRecord()} - ></IconButton> - <IconButton - icon="trash" - action={() => props.deleteRecord()} - ></IconButton> + <IconButton icon="pencil" action={() => props.setAndOpenRecord()}> + (edit) + </IconButton> + <IconButton icon="trash" action={() => props.deleteRecord()}> + (delete) + </IconButton> </div> </div> ); diff --git a/src/components/RecordModal.js b/src/components/RecordModal.js index 81f2791..201c107 100644 --- a/src/components/RecordModal.js +++ b/src/components/RecordModal.js @@ -1,6 +1,6 @@ import Modal from "react-modal"; import Button from "../uikit/Button"; -import Input from "../uikit/Input"; +import Input, { StyledSelect } from "../uikit/Input"; const modalStyle = { content: { @@ -25,6 +25,7 @@ export default function RecordModal(props) { <table className="modal-table"> <thead> <tr> + <th style={{ width: "6em" }}>Type</th> <th style={{ width: "24em" }}>Name</th> <th style={{ width: "8em" }}>Content</th> <th style={{ width: "6em" }}>TTL</th> @@ -33,6 +34,17 @@ export default function RecordModal(props) { <tbody> <tr> <td> + <StyledSelect + onChange={(e) => + setOpenRecord({ ...openRecord, type: e.target.value }) + } + defaultValue="A" + > + <option value="A">A</option> + <option value="AAAA">AAAA</option> + </StyledSelect> + </td> + <td> <Input rows={1} onChange={(e) => diff --git a/src/components/RecordTable.js b/src/components/RecordTable.js index e41fd70..b157023 100644 --- a/src/components/RecordTable.js +++ b/src/components/RecordTable.js @@ -1,5 +1,6 @@ import React from "react"; import Record from "./Record"; +import Button from "../uikit/Button"; // ENUM: sort columns: name, type, value const sortColumns = Object.freeze({ @@ -55,7 +56,14 @@ export default function RecordsTable({ <div class="records-th records-col-ttl">TTL</div> {/* TODO: Stop using NBSP for styling */} <div class="records-th records-col-actions"> - + + <Button + onClick={() => + setAndOpenRecord({ name: "", content: "", ttl: 300, type: "A" }) + } + primary + > + Add + </Button> </div> </div> </div> diff --git a/src/index.js b/src/index.js index 97d63c5..77d8b7b 100644 --- a/src/index.js +++ b/src/index.js @@ -9,6 +9,7 @@ import { AuthProvider } from "./hooks/useAuth"; import { FeaturesProvider } from "./hooks/useFeatures"; import Records from "./routes/Records"; import Zones from "./routes/Zones"; +import Home from "./routes/Home"; const root = ReactDOM.createRoot(document.getElementById("root")); @@ -18,11 +19,11 @@ root.render( <FeaturesProvider> <BrowserRouter> <Routes> - {/* <Route path="/" element={<Home />} /> */} <Route path="/login" element={<Login />} /> <Route path="/signup" element={<SignUp />} /> <Route path="/zones" element={<Zones />} /> <Route path="/zones/:zoneName" element={<Records />} /> + <Route path="/" exact element={<Home />} /> </Routes> </BrowserRouter> </FeaturesProvider> diff --git a/src/routes/Home.js b/src/routes/Home.js new file mode 100644 index 0000000..fff4323 --- /dev/null +++ b/src/routes/Home.js @@ -0,0 +1,14 @@ +import Button from "../uikit/Button"; + +export default function Home() { + return ( + <div> + <h1> + HOSTS<b>dot</b>TXT + </h1> + <Button primary onClick={() => (document.location = "/zones")}> + Zones + </Button> + </div> + ); +} diff --git a/src/routes/Records.css b/src/routes/Records.css index 0ba5c1e..61b9f55 100644 --- a/src/routes/Records.css +++ b/src/routes/Records.css @@ -81,12 +81,12 @@ padding-right: 1em; min-width: calc(48px + 1em); } - +/* .records-col-actions button { background-color: initial; border: none; padding-top: 3px; -} +} */ .modal-table { margin: auto; diff --git a/src/routes/Records.js b/src/routes/Records.js index 0a5c510..239d492 100644 --- a/src/routes/Records.js +++ b/src/routes/Records.js @@ -11,12 +11,14 @@ export function Records() { const [zone, setZone] = React.useState(); const [showModal, setShowModal] = React.useState(false); const [openRecord, setOpenRecord] = React.useState({}); + const [originalRecord, setOriginalRecord] = React.useState({}); const [updateSignal, setUpdateSignal] = React.useState(0); const auth = useAuth(); function setAndOpenRecord(record) { setOpenRecord(record); + setOriginalRecord(record); setShowModal(true); } @@ -25,9 +27,11 @@ export function Records() { if (!updatedName.endsWith(".")) { updatedName += "."; } + if (!updatedName.endsWith(zoneName)) { + updatedName += zoneName; + } const record = { ...openRecord, name: updatedName }; - console.log(record); - if (record.name !== openRecord.name && openRecord.name !== "") { + if (record.name !== originalRecord.name && originalRecord.name !== "") { fetch(`/api/v1/zones/${zoneName}/${record.id}`, { method: "DELETE", headers: { @@ -41,21 +45,43 @@ export function Records() { } }); } - fetch(`/api/v1/zones/${zoneName}/${record.id}`, { - method: "PUT", - headers: { - Authorization: `Bearer ${auth.token}`, - "Content-Type": "application/json", - }, - body: JSON.stringify(record), - }).then((res) => { - if (res.status === 200) { - setShowModal(false); - setUpdateSignal(updateSignal + 1); - } else { - alert("Error updating record"); - } - }); + if (record.id != null) { + fetch(`/api/v1/zones/${zoneName}/${record.id}`, { + method: "PUT", + headers: { + Authorization: `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify(record), + }).then((res) => { + if (res.status === 200) { + setShowModal(false); + setUpdateSignal(updateSignal + 1); + setOpenRecord({}); + setOriginalRecord({}); + } else { + alert("Error updating record"); + } + }); + } else { + fetch(`/api/v1/zones/${zoneName}`, { + method: "PUT", + headers: { + Authorization: `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify(record), + }).then((res) => { + if (res.status === 200) { + setShowModal(false); + setUpdateSignal(updateSignal + 1); + setOpenRecord({}); + setOriginalRecord({}); + } else { + alert("Error creating record"); + } + }); + } } function deleteRecord(id) { @@ -90,7 +116,6 @@ export function Records() { } }); }, [zoneName, auth.token, updateSignal]); - console.log(zone); return ( <RequireAuth> diff --git a/src/uikit/Input.js b/src/uikit/Input.js index 338f8f1..641386f 100644 --- a/src/uikit/Input.js +++ b/src/uikit/Input.js @@ -10,4 +10,15 @@ export const StyledInput = styled("input", { marginBottom: "0.5em", }); +export const StyledSelect = styled("select", { + padding: "0.5em", + border: "1px solid #D4D4D8", + backgroundColor: "#fafafa", + borderRadius: "6px", + // Not my favourite way of doing this, but padding doesn't add to width + width: "calc(100% - 1em)", + fontSize: "1rem", + marginBottom: "0.5em", +}); + export default StyledInput; |