diff --git a/src/components/PageCharacterSheet/Hero/ExperiencePoints/ExperiencePoints.tsx b/src/components/PageCharacterSheet/Hero/ExperiencePoints/ExperiencePoints.tsx new file mode 100644 index 00000000..9b9cc7b2 --- /dev/null +++ b/src/components/PageCharacterSheet/Hero/ExperiencePoints/ExperiencePoints.tsx @@ -0,0 +1,127 @@ +import HelpTooltip from "@/components/HelpTooltip/HelpTooltip"; +import ModalLevelUp from "@/components/ModalLevelUp/ModalLevelUp"; +import { classes } from "@/data/classes"; +import { CharData, ClassNames } from "@/data/definitions"; +import { Button, Flex, Input, Space } from "antd"; +import React from "react"; + +interface ExperiencePointsProps { + classArr: string[]; + character: CharData; + setCharacter: (character: CharData) => void; + setModalIsOpen: (modalIsOpen: boolean) => void; + uid: string | undefined; + id: string | undefined; + setModalTitle: (modalTitle: string) => void; + setModalContent: (modalContent: React.ReactNode) => void; + userIsOwner: boolean; +} + +const ExperiencePoints: React.FC< + ExperiencePointsProps & React.ComponentPropsWithRef<"div"> +> = ({ + className, + classArr, + setModalIsOpen, + character, + setCharacter, + setModalTitle, + uid, + id, + setModalContent, + userIsOwner, +}) => { + const [inputValue, setInputValue] = React.useState(`${character.xp}`); + const showLevelUpModal = () => { + setModalIsOpen(true); + setModalTitle("Level Up"); + setModalContent( + , + ); + }; + const handleInputBlur = () => { + if (!uid || !id) { + return; + } + + // Check if inputValue matches the expected format (optional '-' or '+', followed by numeric characters) + if (!/^[+-]?\d+$/.test(inputValue)) { + console.error("Invalid input"); + return; + } + + // Determine the XP change + let xpChange = 0; + if (inputValue.startsWith("+")) { + xpChange = parseInt(inputValue.slice(1)); + } else if (inputValue.startsWith("-")) { + xpChange = -parseInt(inputValue.slice(1)); + } else { + xpChange = parseInt(inputValue) - character.xp; // Difference between new and old XP + } + + // Apply the XP change + if (!isNaN(xpChange)) { + const updatedXP = character.xp + xpChange; + setCharacter({ + ...character, + xp: updatedXP, + }); + setInputValue(updatedXP.toString()); + } + }; + + const handleInputChange = (event: React.ChangeEvent) => { + setInputValue(event.target.value); + }; + const totalLevelRequirement = classArr + .map((className) => { + const classRequirements = + classes[className as ClassNames]?.experiencePoints; + return classRequirements ? classRequirements[character.level] : 0; // value if using a custom class + }) + .reduce((a, b) => a + b, 0); + return ( + + + { + setTimeout(() => { + e.target.select(); + }, 50); + }} + onChange={handleInputChange} + onBlur={handleInputBlur} + onKeyDown={(event) => { + if (event.key === "Enter") { + handleInputBlur(); + } + }} + name="Experience Points" + id="experience-points" + suffix={character.level < 20 && `/ ${totalLevelRequirement} XP`} + disabled={!userIsOwner} + /> + + {character.level < 20 && ( + + )} + + + + ); +}; + +export default ExperiencePoints; diff --git a/src/components/PageCharacterSheet/Hero/Hero.tsx b/src/components/PageCharacterSheet/Hero/Hero.tsx index 705b111e..def00cbb 100644 --- a/src/components/PageCharacterSheet/Hero/Hero.tsx +++ b/src/components/PageCharacterSheet/Hero/Hero.tsx @@ -6,29 +6,23 @@ import { } from "@ant-design/icons"; import { avatarClassNames } from "@/support/cssSupport"; import { - Avatar, + Flex, Badge, + Avatar, + Divider, Breadcrumb, - BreadcrumbProps, - Button, + Typography, Descriptions, + BreadcrumbProps, DescriptionsProps, - Divider, - Flex, - Input, - Space, - Typography, } from "antd"; import { getAvatar } from "@/support/characterSupport"; -import { ClassNames } from "@/data/definitions"; -import { classes } from "@/data/classes"; -import HelpTooltip from "@/components/HelpTooltip/HelpTooltip"; import BreadcrumbHomeLink from "@/components/BreadcrumbHomeLink/BreadcrumbHomeLink"; import classNames from "classnames"; import AvatarPicker from "@/components/AvatarPicker/AvatarPicker"; import { CharacterDataContext } from "@/contexts/CharacterContext"; -import ModalLevelUp from "@/components/ModalLevelUp/ModalLevelUp"; import { classSplit } from "@/support/classSupport"; +import ExperiencePoints from "./ExperiencePoints/ExperiencePoints"; interface HeroProps { setModalIsOpen: (modalIsOpen: boolean) => void; @@ -46,23 +40,10 @@ const Hero: React.FC> = ({ }) => { const { character, setCharacter, userIsOwner, uid, id } = React.useContext(CharacterDataContext); - const [inputValue, setInputValue] = React.useState(`${character.xp}`); const heroClassNames = classNames("w-full", className); const classArr = classSplit(character.class); - const showLevelUpModal = () => { - setModalIsOpen(true); - setModalTitle("Level Up"); - setModalContent( - , - ); - }; - const showAvatarModal = () => { setModalIsOpen(true); setModalTitle("Change Avatar"); @@ -71,50 +52,6 @@ const Hero: React.FC> = ({ ); }; - const handleInputChange = (event: React.ChangeEvent) => { - setInputValue(event.target.value); - }; - - const handleInputBlur = () => { - if (!uid || !id) { - return; - } - - // Check if inputValue matches the expected format (optional '-' or '+', followed by numeric characters) - if (!/^[+-]?\d+$/.test(inputValue)) { - console.error("Invalid input"); - return; - } - - // Determine the XP change - let xpChange = 0; - if (inputValue.startsWith("+")) { - xpChange = parseInt(inputValue.slice(1)); - } else if (inputValue.startsWith("-")) { - xpChange = -parseInt(inputValue.slice(1)); - } else { - xpChange = parseInt(inputValue) - character.xp; // Difference between new and old XP - } - - // Apply the XP change - if (!isNaN(xpChange)) { - const updatedXP = character.xp + xpChange; - setCharacter({ - ...character, - xp: updatedXP, - }); - setInputValue(updatedXP.toString()); - } - }; - - const totalLevelRequirement = classArr - .map((className) => { - const classRequirements = - classes[className as ClassNames]?.experiencePoints; - return classRequirements ? classRequirements[character.level] : 0; // value if using a custom class - }) - .reduce((a, b) => a + b, 0); - const breadcrumbItems: BreadcrumbProps["items"] = [ { title: , @@ -154,10 +91,10 @@ const Hero: React.FC> = ({ > }> : undefined} size={64} className={avatarClassNames} + icon={!character.avatar ? : undefined} + src={character.avatar ? getAvatar(character.avatar) : undefined} /> @@ -170,58 +107,31 @@ const Hero: React.FC> = ({ {/* Level/Race/Class */} + - {/* Experience Points */} - - - { - setTimeout(() => { - e.target.select(); - }, 50); - }} - onChange={handleInputChange} - onBlur={handleInputBlur} - onKeyDown={(event) => { - if (event.key === "Enter") { - handleInputBlur(); - } - }} - name="Experience Points" - id="experience-points" - suffix={character.level < 20 && `/ ${totalLevelRequirement} XP`} - disabled={!userIsOwner} - /> - - {character.level < 20 && ( - - )} - - -