mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-08-26 10:34:40 +02:00
Add keydowns in updating progerss
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
|
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
|
||||||
|
import { useKeydown } from '../../hooks/use-keydown';
|
||||||
import { useOutsideClick } from '../../hooks/use-outside-click';
|
import { useOutsideClick } from '../../hooks/use-outside-click';
|
||||||
import DownIcon from '../../icons/down.svg';
|
import DownIcon from '../../icons/down.svg';
|
||||||
import SpinnerIcon from '../../icons/spinner.svg';
|
import SpinnerIcon from '../../icons/spinner.svg';
|
||||||
@@ -28,7 +29,8 @@ const statusColors: Record<ResourceProgressType, string> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function TopicProgressButton(props: TopicProgressButtonProps) {
|
export function TopicProgressButton(props: TopicProgressButtonProps) {
|
||||||
const { topicId, resourceId, resourceType, onClose, onShowLoginPopup } = props;
|
const { topicId, resourceId, resourceType, onClose, onShowLoginPopup } =
|
||||||
|
props;
|
||||||
|
|
||||||
const [isUpdatingProgress, setIsUpdatingProgress] = useState(true);
|
const [isUpdatingProgress, setIsUpdatingProgress] = useState(true);
|
||||||
const [progress, setProgress] = useState<ResourceProgressType>('pending');
|
const [progress, setProgress] = useState<ResourceProgressType>('pending');
|
||||||
@@ -56,6 +58,63 @@ export function TopicProgressButton(props: TopicProgressButtonProps) {
|
|||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
}, [topicId, resourceId, resourceType]);
|
}, [topicId, resourceId, resourceType]);
|
||||||
|
|
||||||
|
// Mark as done
|
||||||
|
useKeydown(
|
||||||
|
'd',
|
||||||
|
() => {
|
||||||
|
if (progress === 'done') {
|
||||||
|
onClose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleUpdateResourceProgress('done');
|
||||||
|
},
|
||||||
|
[progress]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Mark as learning
|
||||||
|
useKeydown(
|
||||||
|
'l',
|
||||||
|
() => {
|
||||||
|
if (progress === 'learning') {
|
||||||
|
onClose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleUpdateResourceProgress('learning');
|
||||||
|
},
|
||||||
|
[progress]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Mark as learning
|
||||||
|
useKeydown(
|
||||||
|
's',
|
||||||
|
() => {
|
||||||
|
if (progress === 'skipped') {
|
||||||
|
onClose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleUpdateResourceProgress('skipped');
|
||||||
|
},
|
||||||
|
[progress]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Mark as pending
|
||||||
|
useKeydown(
|
||||||
|
'r',
|
||||||
|
() => {
|
||||||
|
console.log(progress);
|
||||||
|
if (progress === 'pending') {
|
||||||
|
onClose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleUpdateResourceProgress('pending');
|
||||||
|
},
|
||||||
|
[progress]
|
||||||
|
);
|
||||||
|
|
||||||
const handleUpdateResourceProgress = (progress: ResourceProgressType) => {
|
const handleUpdateResourceProgress = (progress: ResourceProgressType) => {
|
||||||
if (isGuest) {
|
if (isGuest) {
|
||||||
onClose();
|
onClose();
|
||||||
@@ -86,10 +145,18 @@ export function TopicProgressButton(props: TopicProgressButtonProps) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const allowMarkingSkipped = ['pending', 'learning', 'done'].includes(progress);
|
const allowMarkingSkipped = ['pending', 'learning', 'done'].includes(
|
||||||
const allowMarkingDone = ['skipped', 'pending', 'learning'].includes(progress);
|
progress
|
||||||
const allowMarkingLearning = ['done', 'skipped', 'pending'].includes(progress);
|
);
|
||||||
const allowMarkingPending = ['skipped', 'done', 'learning'].includes(progress);
|
const allowMarkingDone = ['skipped', 'pending', 'learning'].includes(
|
||||||
|
progress
|
||||||
|
);
|
||||||
|
const allowMarkingLearning = ['done', 'skipped', 'pending'].includes(
|
||||||
|
progress
|
||||||
|
);
|
||||||
|
const allowMarkingPending = ['skipped', 'done', 'learning'].includes(
|
||||||
|
progress
|
||||||
|
);
|
||||||
|
|
||||||
if (isUpdatingProgress) {
|
if (isUpdatingProgress) {
|
||||||
return (
|
return (
|
||||||
@@ -123,51 +190,64 @@ export function TopicProgressButton(props: TopicProgressButtonProps) {
|
|||||||
|
|
||||||
{showChangeStatus && (
|
{showChangeStatus && (
|
||||||
<div
|
<div
|
||||||
className="absolute right-0 top-full mt-1 flex min-w-[128px] flex-col divide-y rounded-md border border-gray-200 bg-white shadow-md [&>button:first-child]:rounded-t-md [&>button:last-child]:rounded-b-md"
|
className="absolute right-0 top-full mt-1 flex min-w-[160px] flex-col divide-y rounded-md border border-gray-200 bg-white shadow-md [&>button:first-child]:rounded-t-md [&>button:last-child]:rounded-b-md"
|
||||||
ref={changeStatusRef!}
|
ref={changeStatusRef!}
|
||||||
>
|
>
|
||||||
{allowMarkingDone && (
|
{allowMarkingDone && (
|
||||||
<button
|
<button
|
||||||
class="px-3 py-1.5 text-left text-sm text-gray-800 hover:bg-gray-100"
|
class="inline-flex justify-between px-3 py-1.5 text-left text-sm text-gray-800 hover:bg-gray-100"
|
||||||
onClick={() => handleUpdateResourceProgress('done')}
|
onClick={() => handleUpdateResourceProgress('done')}
|
||||||
>
|
>
|
||||||
<span
|
<span>
|
||||||
class={`mr-2 inline-block h-2 w-2 rounded-full ${statusColors['done']}`}
|
<span
|
||||||
></span>
|
class={`mr-2 inline-block h-2 w-2 rounded-full ${statusColors['done']}`}
|
||||||
Done
|
></span>
|
||||||
|
Done
|
||||||
|
</span>
|
||||||
|
<span class="text-xs text-gray-500">D</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{allowMarkingLearning && (
|
{allowMarkingLearning && (
|
||||||
<button
|
<button
|
||||||
class="px-3 py-1.5 text-left text-sm text-gray-800 hover:bg-gray-100"
|
class="inline-flex justify-between px-3 py-1.5 text-left text-sm text-gray-800 hover:bg-gray-100"
|
||||||
onClick={() => handleUpdateResourceProgress('learning')}
|
onClick={() => handleUpdateResourceProgress('learning')}
|
||||||
>
|
>
|
||||||
<span
|
<span>
|
||||||
class={`mr-2 inline-block h-2 w-2 rounded-full ${statusColors['learning']}`}
|
<span
|
||||||
></span>
|
class={`mr-2 inline-block h-2 w-2 rounded-full ${statusColors['learning']}`}
|
||||||
In Progress
|
></span>
|
||||||
|
In Progress
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="text-xs text-gray-500">L</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{allowMarkingPending && (
|
{allowMarkingPending && (
|
||||||
<button
|
<button
|
||||||
class="px-3 py-1.5 text-left text-sm text-gray-800 hover:bg-gray-100"
|
class="inline-flex justify-between px-3 py-1.5 text-left text-sm text-gray-800 hover:bg-gray-100"
|
||||||
onClick={() => handleUpdateResourceProgress('pending')}
|
onClick={() => handleUpdateResourceProgress('pending')}
|
||||||
>
|
>
|
||||||
<span
|
<span>
|
||||||
class={`mr-2 inline-block h-2 w-2 rounded-full ${statusColors['pending']}`}
|
<span
|
||||||
></span>
|
class={`mr-2 inline-block h-2 w-2 rounded-full ${statusColors['pending']}`}
|
||||||
Pending
|
></span>
|
||||||
|
Reset
|
||||||
|
</span>
|
||||||
|
<span class="text-xs text-gray-500">R</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{allowMarkingSkipped && (
|
{allowMarkingSkipped && (
|
||||||
<button
|
<button
|
||||||
class="px-3 py-1.5 text-left text-sm text-gray-800 hover:bg-gray-100"
|
class="inline-flex justify-between px-3 py-1.5 text-left text-sm text-gray-800 hover:bg-gray-100"
|
||||||
onClick={() => handleUpdateResourceProgress('skipped')}
|
onClick={() => handleUpdateResourceProgress('skipped')}
|
||||||
>
|
>
|
||||||
<span
|
<span>
|
||||||
class={`mr-2 inline-block h-2 w-2 rounded-full ${statusColors['skipped']}`}
|
<span
|
||||||
></span>
|
class={`mr-2 inline-block h-2 w-2 rounded-full ${statusColors['skipped']}`}
|
||||||
Skip
|
></span>
|
||||||
|
Skip
|
||||||
|
</span>
|
||||||
|
<span class="text-xs text-gray-500">S</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { useEffect, useState } from 'preact/hooks';
|
import { useEffect } from 'preact/hooks';
|
||||||
|
|
||||||
export function useKeydown(keyName: string, callback: any) {
|
export function useKeydown(keyName: string, callback: any, deps: any[] = []) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const listener = (event: any) => {
|
const listener = (event: any) => {
|
||||||
if (event.key.toLowerCase() === keyName.toLowerCase()) {
|
if (event.key.toLowerCase() === keyName.toLowerCase()) {
|
||||||
@@ -12,5 +12,5 @@ export function useKeydown(keyName: string, callback: any) {
|
|||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('keydown', listener);
|
window.removeEventListener('keydown', listener);
|
||||||
};
|
};
|
||||||
}, []);
|
}, deps);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user