-
-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
232 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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
This file contains 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
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; |
This file contains 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
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; |