//Lib
import classes from './RepoManage.module.css';
import { IconAlertCircle, IconX } from '@tabler/icons';
import { useState } from 'react';
import { useRouter } from 'next/router';
import { toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { useForm, Controller } from 'react-hook-form';
import { SpinnerDotted } from 'spinners-react';
import Select from 'react-select';
export default function RepoManage(props) {
////Var
let targetRepo;
const router = useRouter();
const {
register,
handleSubmit,
control,
formState: { errors, isSubmitting, isValid },
} = useForm({ mode: 'onChange' });
//List of possible times for alerts
const alertOptions = [
{ value: 3600, label: '1 hour' },
{ value: 21600, label: '6 hours' },
{ value: 43200, label: '12 hours' },
{ value: 90000, label: '1 day' },
{ value: 172800, label: '2 days' },
{ value: 259200, label: '3 days' },
{ value: 345600, label: '4 days' },
{ value: 432000, label: '5 days' },
{ value: 518400, label: '6 days' },
{ value: 604800, label: '7 days' },
{ value: 864000, label: '10 days' },
{ value: 1209600, label: '14 days' },
{ value: 2592000, label: '30 days' },
];
const toastOptions = {
position: 'top-right',
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
};
////State
const [deleteDialog, setDeleteDialog] = useState(false);
const [isLoading, setIsLoading] = useState(false);
////Functions
//router.query.slug is undefined for few milliseconds on first render for a direct URL access (https://github.com/vercel/next.js/discussions/11484).
//If I call repoManage with edit mode (props), i'm firstly waiting that router.query.slug being available before rendering.
if (!router.query.slug && props.mode == 'edit') {
return (
);
} else if (props.mode == 'edit') {
for (let element in props.repoList) {
if (props.repoList[element].id == router.query.slug) {
targetRepo = props.repoList[element];
}
}
//If the ID does not exist > 404
if (!targetRepo) {
router.push('/404');
return null;
}
}
//Delete a repo
const deleteHandler = async () => {
//API Call for delete
fetch('/api/repo/id/' + router.query.slug + '/delete', {
method: 'DELETE',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify({ toDelete: true }),
})
.then((response) => {
if (response.ok) {
toast.success(
'🗑 The repository #' +
router.query.slug +
' has been successfully deleted',
toastOptions
);
router.replace('/');
} else {
toast.error('An error has occurred', toastOptions);
router.replace('/');
console.log('Fail to delete');
}
})
.catch((error) => {
toast.error('An error has occurred', toastOptions);
router.replace('/');
console.log(error);
});
};
//Form submit Handler for ADD or EDIT a repo
const formSubmitHandler = async (dataForm) => {
//Loading button on submit to avoid multiple send.
setIsLoading(true);
//ADD a repo
if (props.mode == 'add') {
const newRepo = {
alias: dataForm.alias,
size: dataForm.size,
sshPublicKey: dataForm.sshkey,
comment: dataForm.comment,
alert: dataForm.alert.value,
};
//POST API to send new repo
await fetch('/api/repo/add', {
method: 'POST',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify(newRepo),
})
.then((response) => {
if (response.ok) {
toast.success(
'New repository added ! 🥳',
toastOptions
);
router.replace('/');
} else {
toast.error('An error has occurred', toastOptions);
router.replace('/');
console.log('Fail to post');
}
})
.catch((error) => {
toast.error('An error has occurred', toastOptions);
router.replace('/');
console.log(error);
});
//EDIT a repo
} else if (props.mode == 'edit') {
const dataEdited = {
alias: dataForm.alias,
size: dataForm.size,
sshPublicKey: dataForm.sshkey,
comment: dataForm.comment,
alert: dataForm.alert.value,
};
await fetch('/api/repo/id/' + router.query.slug + '/edit', {
method: 'PUT',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify(dataEdited),
})
.then((response) => {
if (response.ok) {
toast.success(
'The repository #' +
targetRepo.id +
' has been successfully edited !',
toastOptions
);
router.replace('/');
} else {
toast.error('An error has occurred', toastOptions);
router.replace('/');
console.log('Fail to PUT');
}
})
.catch((error) => {
toast.error('An error has occurred', toastOptions);
router.replace('/');
console.log(error);
});
}
};
return (
<>
{deleteDialog ? (
Delete the repository{' '}
#{targetRepo.id}
{' '}
?
You are about to permanently delete the
repository #{targetRepo.id} and all the
backups it contains.
The data will not be recoverable and it will not
be possible to go back.
{isLoading ? (
) : (
<>
>
)}
) : (
{props.mode == 'edit' && (
Edit the repository{' '}
#{targetRepo.id}
)}
{props.mode == 'add' &&
Add a repository
}
{props.mode == 'edit' ? (
) : null}
)}
>
);
}