From 850e2afd9a56985256775f28139adc3953607375 Mon Sep 17 00:00:00 2001 From: meziyum Date: Thu, 5 Oct 2023 16:56:37 +0530 Subject: [PATCH 1/4] Initial Refactor --- .../parts/{achievement.js => achievement.tsx} | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) rename src/client/components/forms/parts/{achievement.js => achievement.tsx} (90%) diff --git a/src/client/components/forms/parts/achievement.js b/src/client/components/forms/parts/achievement.tsx similarity index 90% rename from src/client/components/forms/parts/achievement.js rename to src/client/components/forms/parts/achievement.tsx index 472f74eca5..959c0cc320 100644 --- a/src/client/components/forms/parts/achievement.js +++ b/src/client/components/forms/parts/achievement.tsx @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Max Prettyjohns + * 2023 Meziyum * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +34,6 @@ const maxAchievementProgress = { 7: 1, 8: 10, 9: 100, - // eslint-disable-next-line sort-keys 10: 10, 11: 7, 12: 30, @@ -57,8 +57,18 @@ const maxAchievementProgress = { 30: 100 }; -function Achievement(props) { - const {achievement, counter, unlocked} = props; +interface Props { + achievement: { + id: number; + name: string; + description: string; + badgeUrl: string; + }, + counter: number; + unlocked: boolean; +}; + +function Achievement({achievement, counter, unlocked}: Props): React.JSX.Element { const {id, name, description, badgeUrl} = achievement; const imgElement = unlocked ? ( Date: Thu, 5 Oct 2023 17:04:23 +0530 Subject: [PATCH 2/4] Added JSDoc --- .../components/forms/parts/achievement.tsx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/client/components/forms/parts/achievement.tsx b/src/client/components/forms/parts/achievement.tsx index 959c0cc320..1dcf54ff82 100644 --- a/src/client/components/forms/parts/achievement.tsx +++ b/src/client/components/forms/parts/achievement.tsx @@ -68,6 +68,25 @@ interface Props { unlocked: boolean; }; +/** + * Achievement Component + * + * A React component that displays an achievement card with its details, including name, + * description, badge image, and progress if the achievement is locked. + * + * @component + * + * @param {Object} props - The props for the Achievement component. + * @param {Object} props.achievement - The achievement object containing details. + * @param {number} props.achievement.id - The unique ID of the achievement. + * @param {string} props.achievement.name - The name of the achievement. + * @param {string} props.achievement.description - The description of the achievement. + * @param {string} props.achievement.badgeUrl - The URL of the achievement badge image. + * @param {number} props.counter - The current progress or counter for the achievement. + * @param {boolean} props.unlocked - A boolean indicating whether the achievement is unlocked. + * + * @returns {JSX.Element} The rendered Achievement card component. + */ function Achievement({achievement, counter, unlocked}: Props): React.JSX.Element { const {id, name, description, badgeUrl} = achievement; const imgElement = unlocked ? ( From 9ef902ca53d2167505df7ce3e828331dd85e4c80 Mon Sep 17 00:00:00 2001 From: Monkey Do Date: Mon, 19 Feb 2024 18:34:40 +0100 Subject: [PATCH 3/4] refactor(profile): more Achievements refactoring Typescriptification and cleaning up duplicate/unused props --- .../components/forms/parts/achievement.tsx | 52 ++++--------------- src/client/components/input/drag-and-drop.tsx | 44 +++++++--------- .../pages/parts/editor-achievements.js | 2 - 3 files changed, 30 insertions(+), 68 deletions(-) diff --git a/src/client/components/forms/parts/achievement.tsx b/src/client/components/forms/parts/achievement.tsx index 1dcf54ff82..7ca03dc6e2 100644 --- a/src/client/components/forms/parts/achievement.tsx +++ b/src/client/components/forms/parts/achievement.tsx @@ -18,12 +18,13 @@ */ import * as bootstrap from 'react-bootstrap'; +import type {Achievement} from '../../input/drag-and-drop'; import DragAndDropImage from '../../input/drag-and-drop-image'; -import PropTypes from 'prop-types'; import React from 'react'; const {Card, Col, Container, Row} = bootstrap; +/* eslint-disable sort-keys */ const maxAchievementProgress = { 1: 1, 2: 50, @@ -56,17 +57,11 @@ const maxAchievementProgress = { 29: 10, 30: 100 }; +/* eslint-enable sort-keys */ -interface Props { - achievement: { - id: number; - name: string; - description: string; - badgeUrl: string; - }, - counter: number; - unlocked: boolean; -}; +interface AchievementComponentProps { + achievement: Achievement +} /** * Achievement Component @@ -77,36 +72,26 @@ interface Props { * @component * * @param {Object} props - The props for the Achievement component. - * @param {Object} props.achievement - The achievement object containing details. - * @param {number} props.achievement.id - The unique ID of the achievement. - * @param {string} props.achievement.name - The name of the achievement. - * @param {string} props.achievement.description - The description of the achievement. - * @param {string} props.achievement.badgeUrl - The URL of the achievement badge image. + * @param {Achievement} props.achievement - The achievement object containing details. * @param {number} props.counter - The current progress or counter for the achievement. * @param {boolean} props.unlocked - A boolean indicating whether the achievement is unlocked. * * @returns {JSX.Element} The rendered Achievement card component. */ -function Achievement({achievement, counter, unlocked}: Props): React.JSX.Element { - const {id, name, description, badgeUrl} = achievement; +function AchievementComponent({achievement}: AchievementComponentProps): JSX.Element { + const {id, name, description, badgeUrl, counter, unlocked} = achievement; const imgElement = unlocked ? ( ) : ( {name} ); @@ -136,21 +121,6 @@ function Achievement({achievement, counter, unlocked}: Props): React.JSX.Element ); } -Achievement.displayName = 'achievement'; - -Achievement.propTypes = { - achievement: PropTypes.shape({ - badgeUrl: PropTypes.string, - description: PropTypes.string, - id: PropTypes.number, - name: PropTypes.string - }).isRequired, - counter: PropTypes.number, - unlocked: PropTypes.bool -}; -Achievement.defaultProps = { - counter: 0, - unlocked: false -}; +AchievementComponent.displayName = 'achievement'; -export default Achievement; +export default AchievementComponent; diff --git a/src/client/components/input/drag-and-drop.tsx b/src/client/components/input/drag-and-drop.tsx index 306bcad22c..fed54f788b 100644 --- a/src/client/components/input/drag-and-drop.tsx +++ b/src/client/components/input/drag-and-drop.tsx @@ -17,7 +17,6 @@ */ import * as bootstrap from 'react-bootstrap'; -import PropTypes from 'prop-types'; import React from 'react'; @@ -31,10 +30,20 @@ const {useState, useCallback} = React; * @property {string} badgeUrl - The source URL of the achievement's badge image. * @property {number} id - The ID of the achievement. */ -type Achievement = { - name: string; +export type Achievement = { badgeUrl: string | null; + counter:number; + description: string; id: number; + name: string; + unlocked: boolean; +}; +type AchievementForDisplay = Pick; + +const blankBadge:AchievementForDisplay = { + badgeUrl: '/images/blankbadge.svg', + id: null, + name: 'drag badge to set' }; /** @@ -56,18 +65,14 @@ type Props = { * @returns {JSX.Element} A React component that displays a drag-and-drop card for an achievement. */ function DragAndDrop({name, initialAchievement}: Props): JSX.Element { - const [achievement, setAchievement] = useState(initialAchievement); + const [achievement, setAchievement] = useState(initialAchievement); const handleClick = useCallback((event: React.MouseEvent) => { event.preventDefault(); - setAchievement({ - badgeUrl: '/images/blankbadge.svg', - id: null, - name: 'drag badge to set' - }); - }); + setAchievement(blankBadge); + }, []); const handleDragOver = useCallback((event: React.DragEvent) => { event.preventDefault(); - }); + }, []); const handleDrop = useCallback((event: React.DragEvent) => { event.preventDefault(); let data; @@ -83,7 +88,7 @@ function DragAndDrop({name, initialAchievement}: Props): JSX.Element { id: data.id, name: data.name }); - }); + }, [setAchievement]); return ( ); if (achievement.unlocked) { From 7873c961c92e2330b266df8de79457c3b53d785d Mon Sep 17 00:00:00 2001 From: Monkey Do Date: Mon, 19 Feb 2024 18:45:43 +0100 Subject: [PATCH 4/4] chore(types): Remove prop-types Now that it's a typescript file --- src/client/components/input/drag-and-drop-image.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/client/components/input/drag-and-drop-image.tsx b/src/client/components/input/drag-and-drop-image.tsx index 82caa7b788..33564578b8 100644 --- a/src/client/components/input/drag-and-drop-image.tsx +++ b/src/client/components/input/drag-and-drop-image.tsx @@ -16,7 +16,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -import PropTypes from 'prop-types'; import React from 'react'; @@ -71,11 +70,5 @@ function DragAndDropImage({achievementId, achievementName, height, src}: Props): } DragAndDropImage.displayName = 'DragAndDropImage'; -DragAndDropImage.propTypes = { - achievementId: PropTypes.number.isRequired, - achievementName: PropTypes.string.isRequired, - height: PropTypes.string.isRequired, - src: PropTypes.string.isRequired -}; export default DragAndDropImage;