diff --git a/.gitignore b/.gitignore
index 25d78f8..f08ed5c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,5 +3,4 @@ node_modules
data/kronos.bolt
bin
*.sqlite
-.idea/
-.husky/
\ No newline at end of file
+.idea/
\ No newline at end of file
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100755
index 0000000..d24fdfc
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+. "$(dirname -- "$0")/_/husky.sh"
+
+npx lint-staged
diff --git a/ui/src/components/atoms/ToggleAllCheckbox/ToggleAllCheckbox.tsx b/ui/src/components/atoms/ToggleAllCheckbox/ToggleAllCheckbox.tsx
new file mode 100644
index 0000000..e3ba389
--- /dev/null
+++ b/ui/src/components/atoms/ToggleAllCheckbox/ToggleAllCheckbox.tsx
@@ -0,0 +1,53 @@
+import { Checkbox, CheckboxProps } from '@/components/chakra/checkbox.tsx';
+
+interface ToggleAllCheckboxProps extends CheckboxProps {
+ /**
+ * The array of the checked items.
+ */
+ checkedItems: unknown[];
+
+ /**
+ * The array that contains all the check-able items.
+ */
+ allItems: unknown[];
+
+ /**
+ * Callback triggered when the checkbox is pressed when all the items are checked.
+ */
+ onResetCheckedItems(): void;
+
+ /**
+ * Callback triggered when the checkbox is pressed and not all the items are checked.
+ */
+ onCheckAllItems(): void;
+}
+
+export default function ToggleAllCheckbox(props: ToggleAllCheckboxProps) {
+ const {
+ checkedItems,
+ allItems,
+ onCheckAllItems,
+ onResetCheckedItems,
+ ...rest
+ } = props;
+ const areAllChecked = checkedItems.length === allItems.length;
+ const indeterminate = checkedItems.length > 0 && !areAllChecked;
+
+ const handleCheck = () => {
+ if (areAllChecked) {
+ return onResetCheckedItems();
+ }
+
+ onCheckAllItems();
+ };
+
+ return (
+