Skip to content

Commit

Permalink
⚒️ Add new options: delete & edit.
Browse files Browse the repository at this point in the history
  • Loading branch information
pheralb committed Nov 21, 2022
1 parent a5b24f7 commit 35e1e80
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/components/functions/create/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const Create = () => {
icon: "🥳",
style: {
borderRadius: "10px",
background: "#28283E",
background: "#121212",
color: "#fff",
},
});
Expand Down
112 changes: 112 additions & 0 deletions src/components/functions/delete/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import { trpc } from "@/utils/trpc";
import { useRouter } from "next/router";
import { Button } from "@/ui";
import toast from "react-hot-toast";
import Alert from "@/ui/alert";
import { BiTrash } from "react-icons/bi";
import { nanoid } from "nanoid";

interface DeleteProps {
id: number;
}

const Delete = (props: DeleteProps) => {
const {
handleSubmit,
register,
getValues,
formState: { errors },
} = useForm();
const [loading, setLoading] = useState(false);
const router = useRouter();
const [disabled, setDisabled] = useState(false);
const [validate, setValidate] = useState(String);

useEffect(() => {
const random = nanoid(5);
setValidate(random);
if (validate === random) {
setDisabled(true);
}
}, []);

const { mutate, error } = trpc.useMutation(["links.delete-link"], {
onSuccess: () => {
router.reload();
setLoading(false);
toast("Link deleted successfully", {
icon: "🥳",
style: {
borderRadius: "10px",
background: "#121212",
color: "#fff",
},
});
},
onError: () => {
setLoading(false);
alert("Error");
},
});

const onSubmit = () => {
if (validate === getValues("validate")) {
setLoading(true);
mutate({
linkId: props.id,
});
} else {
toast("The values do not match. Check the validation.", {
icon: "🤔",
style: {
borderRadius: "10px",
background: "#121212",
color: "#fff",
},
});
}
};

return (
<form onSubmit={handleSubmit(onSubmit)}>
{error && (
<Alert>
<p>{error.message}</p>
</Alert>
)}
<Alert>
<p>
Are you sure you want to delete this link? This action is
irreversible.
</p>
</Alert>
<div className="mb-5">
<p>Enter the following to confirm:</p>
<p className="text-gray-400">{validate}</p>
<div className="mt-1">
<input
type="text"
placeholder="..."
className="rounded-md px-4 py-2 w-full focus:border-none bg-midnightLight text-white"
{...register("validate", { required: true, maxLength: 20 })}
/>
</div>
</div>
<div className="flex justify-end mt-5">
<Button
type="submit"
disabled={loading}
isLoading={loading}
loadingText="Deleting your link..."
icon={<BiTrash size={18} />}
>
Delete link
</Button>
</div>
</form>
);
};

export default Delete;
119 changes: 119 additions & 0 deletions src/components/functions/edit/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import { EditLinkInput } from "@/schema/link.schema";
import { trpc } from "@/utils/trpc";
import { useRouter } from "next/router";
import { Button } from "@/ui";
import toast from "react-hot-toast";
import Alert from "@/ui/alert";
import { BiCheck } from "react-icons/bi";

interface EditProps {
id: number;
slug: string;
url: string;
description: string;
}

const Edit = (props: EditProps) => {
const {
handleSubmit,
setValue,
register,
formState: { errors },
} = useForm<EditLinkInput>();
const [loading, setLoading] = useState(false);
const router = useRouter();
const [disabled, setDisabled] = useState(false);

const { mutate, error } = trpc.useMutation(["links.edit-link"], {
onSuccess: () => {
router.reload();
setLoading(false);
toast("Link edited successfully", {
icon: "🥳",
style: {
borderRadius: "10px",
background: "#121212",
color: "#fff",
},
});
},
onError: () => {
setLoading(false);
alert("Error");
},
});

const onSubmit = (values: EditLinkInput) => {
setValue("slug", props.slug);
setLoading(true);
mutate({
slug: props.slug,
url: values.url,
description: values.description,
});
};

return (
<form onSubmit={handleSubmit(onSubmit)}>
{error && (
<Alert>
<p>{error.message}</p>
</Alert>
)}
<div className="mb-5">
<label htmlFor="url">Enter the new URL:</label>
<input
id="url"
type="text"
placeholder="https://"
defaultValue={props.url}
className="rounded-md px-4 py-2 w-full focus:border-none mt-1 bg-midnightLight text-white"
{...register("url", {
required: {
value: true,
message: "Please enter a URL.",
},
minLength: {
value: 8,
message:
"Please enter a valid URL. It should be at least 8 characters long.",
},
pattern: {
value: /^https?:\/\//i,
message:
"Please enter a valid URL. It should start with http:// or https://",
},
})}
/>
{errors.url && <Alert className="mt-2">{errors.url.message}</Alert>}
</div>
<div className="mb-3">
<label htmlFor="description">Description:</label>
<textarea
id="description"
className="rounded-md px-4 py-2 w-full focus:border-none mt-1 bg-midnightLight text-white"
defaultValue={props.description}
{...register("description")}
/>
</div>
<Alert>
<p>This action is irreversible.</p>
</Alert>
<div className="flex justify-end mt-5">
<Button
type="submit"
disabled={loading}
isLoading={loading}
loadingText="Editing your link..."
icon={<BiCheck size={18} />}
>
Edit link
</Button>
</div>
</form>
);
};

export default Edit;

0 comments on commit 35e1e80

Please sign in to comment.