From deea0f3d7bd6adae65c25ead449508624d50c865 Mon Sep 17 00:00:00 2001 From: "alekseev.andrey45" Date: Mon, 22 Jul 2024 12:48:15 +0300 Subject: [PATCH 1/2] interview --- .idea/.gitignore | 5 ++ .idea/interview.iml | 12 +++ .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 ++ src/components/App.tsx | 183 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 214 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/interview.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 src/components/App.tsx diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/interview.iml b/.idea/interview.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/interview.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..6b972bf --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/components/App.tsx b/src/components/App.tsx new file mode 100644 index 0000000..6f5dd76 --- /dev/null +++ b/src/components/App.tsx @@ -0,0 +1,183 @@ +import { useCallback, useState } from "react"; + +import { Api } from "../utils/Api"; + +/* + Легенда: + Необходимо отобразить список ключей (произвольные строки), запрашиваемый с бэкенда. + При нажатии кнопки "Сгенерировать ключ" необходимо сгенерировать новый ключ (апи запрос) и отобразить его в списке. + Каждый ключ можно использовать. В таком случае он должен изменить свое визуальное отображение и увеличить счетчик использованных ключей. + Каждый ключ можно удалить. При удалении использованного ключа, счетчик использованных ключей уменьшается (счетчику важны только неудаленные использованные ключи) + + Для поддержания актуального списка ключей необходимо обновлять список каждые 30 секунд. При получении от апи новых ключей считать их неиспользованными + */ + +export function App() { + const [keys, setKeys] = useState(null); + const [isKeysRequested, setIsKeysRequested] = useState(false); + + const [isLoading, setLoadingState] = useState(false); + const [countUsedKeys, setCountUsedKeys] = useState(0); + + const toggleLoading = useCallback(() => { + setLoadingState(!isLoading); + }, [isLoading]); + + const incrementUsedKeys = () => { + setCountUsedKeys((prevValue) => prevValue++); + } + + const decrementUsedKeys = useCallback(() => { + setCountUsedKeys((prevValue) => prevValue--); + }, []); + + const addKey = useCallback(async () => { + toggleLoading(); + + const key = await Api.generateKey(); + setKeys((prevKeys) => prevKeys.push(key)); + + toggleLoading(); + }, [toggleLoading]); + + const removeKey = useCallback((value) => { + setKeys((prevKeys) => prevKeys.filter((key) => key !== value)); + }, []); + + if (!isKeysRequested) { + setIsKeysRequested(true); + Api.loadKeys().then((response) => { + setKeys(response); + setInterval(() => { + Api.loadKeys().then((response) => { + setKeys(response); + }) + }, 30000); + }).catch(e => { + setIsKeysRequested(false); + }) + } + + return ( +
+
+

Всего ключей: {keys.length}

+

Использовано текущих ключей: {countUsedKeys}

+
+ + {!keys.length &&
Список ключей пуст
} + + {keys.length && ( +
+ {keys.map((key) => ( + + ))} +
+ )} + +
+
+
+ ); +}; + +export function Button({ + size, + label, + color, + onClick, + disabled, + isLoading, + }) { + const className = useMemo( + () => cn([size && `size_${size}`, color && `color_${color}`]), + [color, size] + ); + + return ( + + ); +}; + +export function Key({ + value, + removeKey, + incrementUsedKeys, + decrementUsedKeys, + }) { + const [isUsed, setUsedState] = useState(false); + const [isLoading, setLoadingState] = useState(false); + + const toggleLoading = useCallback(() => { + setLoadingState(!isLoading); + }, [isLoading]); + + const applyKey = useCallback( + async (value) => { + if (isUsed) return; + + toggleLoading(); + await Api.addUsedKey(value); + toggleLoading(); + + setUsedState(true); + incrementUsedKeys(); + }, + [incrementUsedKeys, isUsed, toggleLoading] + ); + + useEffect(async () => { + return async () => { + if (!isUsed) return; + + decrementUsedKeys(); + await Api.removeUsedKey(value); + }; + }, [decrementUsedKeys, isUsed, value]); + + const valueClassNames = useMemo( + () => cn(["key__value", isUsed && "key__value_used"]), + [isUsed] + ); + + const buttonLabel = isUsed ? "Использован" : "Использовать"; + + return ( +
+
{value}
+ +
+
+
+ ); +}; From 7f611c28fbe598d2ce6262cc97124b8757d0c38d Mon Sep 17 00:00:00 2001 From: "alekseev.andrey45" Date: Mon, 22 Jul 2024 12:49:26 +0300 Subject: [PATCH 2/2] remove .idea --- .gitignore | 41 +++++++++++++++++++++++++++++++++++++++++ .idea/.gitignore | 5 ----- .idea/interview.iml | 12 ------------ .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 5 files changed, 41 insertions(+), 31 deletions(-) create mode 100644 .gitignore delete mode 100644 .idea/.gitignore delete mode 100644 .idea/interview.iml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..08f9fcb --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ + +# dependencies +/node_modules + +# testing +/coverage + +# build +/build + +# envs +/.env + +# Misc +.DS_Store + +# Editors and IDEs +.idea +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# Logs +npm-debug.log* +npm-error.log* +yarn-debug.log* +yarn-error.log* + +# awesome-typescript-loader + babel-loader cache +.awcache + + +# videoshots +videoshot-with-error/ + +.eslintinfo +.stylelintinfo +.todo +todo \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index b58b603..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/interview.iml b/.idea/interview.iml deleted file mode 100644 index 24643cc..0000000 --- a/.idea/interview.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 6b972bf..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file