aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGalen Guyer <galen@galenguyer.com>2022-08-31 14:09:52 -0400
committerGalen Guyer <galen@galenguyer.com>2022-08-31 14:09:52 -0400
commit641bcfe174daf231209acc2ecee1dfa681471089 (patch)
tree9f1ffc6841b18672f7189c90fa43117da6cae980
parent4dc20b3e1a90eefd22354f69e058d14a56364689 (diff)
Add creation of new records in a zone
-rw-r--r--src/components/IconButton.js4
-rw-r--r--src/components/Record.js14
-rw-r--r--src/components/RecordModal.js14
-rw-r--r--src/components/RecordTable.js10
-rw-r--r--src/index.js3
-rw-r--r--src/routes/Home.js14
-rw-r--r--src/routes/Records.css4
-rw-r--r--src/routes/Records.js61
-rw-r--r--src/uikit/Input.js11
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">
- +&nbsp;&nbsp;&nbsp;&nbsp;
+ <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;