diff --git a/components/WeaponHovercard/index.scss b/components/WeaponHovercard/index.scss new file mode 100644 index 00000000..4e540a09 --- /dev/null +++ b/components/WeaponHovercard/index.scss @@ -0,0 +1,41 @@ +.Weapon.Hovercard { + .skills { + display: flex; + flex-direction: row; + justify-content: space-between; + padding-right: $unit * 2; + + .axSkill { + align-items: center; + display: flex; + flex-direction: row; + + &.primary img { + height: 64px; + width: 64px; + } + + &.secondary { + gap: $unit * 1.5; + + img { + height: 36px; + width: 36px; + } + } + + span { + font-size: $font-small; + font-weight: $medium; + text-align: center; + } + } + } + + .weaponKeys { + display: flex; + flex-direction: column; + font-size: $normal; + gap: $unit / 2; + } +} \ No newline at end of file diff --git a/components/WeaponHovercard/index.tsx b/components/WeaponHovercard/index.tsx new file mode 100644 index 00000000..6126438a --- /dev/null +++ b/components/WeaponHovercard/index.tsx @@ -0,0 +1,161 @@ +import React from 'react' +import * as HoverCard from '@radix-ui/react-hover-card' + +import WeaponLabelIcon from '~components/WeaponLabelIcon' +import UncapIndicator from '~components/UncapIndicator' + +import { axData } from '~utils/axData' + +import './index.scss' +import { keys } from 'lodash' + +interface Props { + gridWeapon: GridWeapon + children: React.ReactNode +} + +interface KeyNames { + [key: string]: { + en: string, + jp: string + } +} + +const WeaponHovercard = (props: Props) => { + const Element = ['null', 'wind', 'fire', 'water', 'earth', 'dark', 'light'] + const Proficiency = ['none', 'sword', 'dagger', 'axe', 'spear', 'bow', 'staff', 'fist', 'harp', 'gun', 'katana'] + const WeaponKeyNames: KeyNames = { + '2': { + en: 'Pendulum', + jp: '' + }, + '3': { + en: 'Teluma', + jp: '' + }, + '17': { + en: 'Gauph Key', + jp: '' + }, + '22': { + en: 'Emblem', + jp: '' + } + } + + const tintElement = (props.gridWeapon.object.element == 0 && props.gridWeapon.element) ? Element[props.gridWeapon.element] : Element[props.gridWeapon.object.element] + const wikiUrl = `https://gbf.wiki/${props.gridWeapon.object.name.en.replaceAll(' ', '_')}` + + const createPrimaryAxSkillString = () => { + const primaryAxSkills = axData[props.gridWeapon.object.ax - 1] + + if (props.gridWeapon.ax) { + const simpleAxSkill = props.gridWeapon.ax[0] + const axSkill = primaryAxSkills.find(skill => skill.id == simpleAxSkill.modifier) + + return `${axSkill?.name.en} +${simpleAxSkill.strength}${ (axSkill?.suffix) ? axSkill.suffix : '' }` + } + + return '' + } + + const createSecondaryAxSkillString = () => { + const primaryAxSkills = axData[props.gridWeapon.object.ax - 1] + + if (props.gridWeapon.ax) { + const primarySimpleAxSkill = props.gridWeapon.ax[0] + const secondarySimpleAxSkill = props.gridWeapon.ax[1] + + const primaryAxSkill = primaryAxSkills.find(skill => skill.id == primarySimpleAxSkill.modifier) + + if (primaryAxSkill && primaryAxSkill.secondary) { + const secondaryAxSkill = primaryAxSkill.secondary.find(skill => skill.id == secondarySimpleAxSkill.modifier) + return `${secondaryAxSkill?.name.en} +${secondarySimpleAxSkill.strength}${ (secondaryAxSkill?.suffix) ? secondaryAxSkill.suffix : '' }` + } + } + + return '' + } + + function weaponImage() { + const weapon = props.gridWeapon.object + + if (props.gridWeapon.object.element == 0 && props.gridWeapon.element) + return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}_${props.gridWeapon.element}.jpg` + else + return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}.jpg` + } + + const keysSection = ( +
+ { (WeaponKeyNames[props.gridWeapon.object.series]) ? +
{ WeaponKeyNames[props.gridWeapon.object.series].en }s
: '' + } + + { (props.gridWeapon.weapon_keys) ? + Array.from(Array(props.gridWeapon.weapon_keys.length)).map((x, i) => { + return ( +
+ {props.gridWeapon.weapon_keys![i].name.en} +
+ ) + }) : '' } +
+ ) + + const axSection = ( +
+
AX Skills
+
+
+ + {createPrimaryAxSkillString()} +
+ + { (props.gridWeapon.ax && props.gridWeapon.ax[1].modifier && props.gridWeapon.ax[1].strength) ? +
+ + {createSecondaryAxSkillString()} +
: ''} +
+
+ ) + + return ( + + + { props.children } + + +
+
+

{ props.gridWeapon.object.name.en }

+ {props.gridWeapon.object.name.en} +
+
+
+ { (props.gridWeapon.object.element !== 0 || (props.gridWeapon.object.element === 0 && props.gridWeapon.element != null)) ? + + : '' } + +
+ +
+
+ + { (props.gridWeapon.object.ax > 0 && props.gridWeapon.ax && props.gridWeapon.ax[0].modifier && props.gridWeapon.ax[0].strength ) ? axSection : '' } + { (props.gridWeapon.weapon_keys && props.gridWeapon.weapon_keys.length > 0) ? keysSection : '' } + View more on gbf.wiki + +
+
+ ) +} + +export default WeaponHovercard + diff --git a/components/WeaponUnit/index.tsx b/components/WeaponUnit/index.tsx index f90067af..67a8f7a8 100644 --- a/components/WeaponUnit/index.tsx +++ b/components/WeaponUnit/index.tsx @@ -3,6 +3,7 @@ import classnames from 'classnames' import SearchModal from '~components/SearchModal' import WeaponModal from '~components/WeaponModal' +import WeaponHovercard from '~components/WeaponHovercard' import UncapIndicator from '~components/UncapIndicator' import Button from '~components/Button' @@ -88,28 +89,38 @@ const WeaponUnit = (props: Props) => { ) - return ( + const unitContent = (
-
- { (props.editable && gridWeapon && canBeModified(gridWeapon)) ? - -
-
-
: '' } - { (props.editable) ? editableImage : image } - { (gridWeapon) ? - : '' - } -

{weapon?.name.en}

-
+ { (props.editable && gridWeapon && canBeModified(gridWeapon)) ? + +
+
+
: '' } + { (props.editable) ? editableImage : image } + { (gridWeapon) ? + : '' + } +

{weapon?.name.en}

+
+ ) + + const withHovercard = ( + + {unitContent} + + ) + + return ( +
+ { (gridWeapon) ? withHovercard : unitContent }
) } diff --git a/styles/globals.scss b/styles/globals.scss index 4f26f3f7..46393f74 100644 --- a/styles/globals.scss +++ b/styles/globals.scss @@ -175,6 +175,99 @@ select { } } +.Hovercard { + background: #222; + border-radius: $unit; + color: white; + display: flex; + flex-direction: column; + gap: $unit * 2; + padding: $unit * 2; + min-width: 300px; + + .top { + display: flex; + flex-direction: column; + gap: $unit / 2; + + .title { + align-items: center; + display: flex; + flex-direction: row; + gap: $unit * 2; + + h4 { + flex-grow: 1; + font-size: $font-medium; + line-height: 1.2; + min-width: 140px; + } + + img { + height: auto; + width: 100px; + } + } + + .subInfo { + align-items: center; + display: flex; + flex-direction: row; + gap: $unit * 2; + + .icons { + display: flex; + flex-direction: row; + flex-grow: 1; + gap: $unit; + } + + .UncapIndicator { + width: 100px; + } + } + } + + section { + h5 { + font-size: $font-small; + font-weight: $medium; + opacity: 0.7; + + &.wind { + color: $wind-bg-light; + } + + &.fire { + color: $fire-bg-light; + } + + &.water { + color: $water-bg-light; + } + + &.earth { + color: $earth-bg-light; + } + + &.dark { + color: $dark-bg-light; + } + + + &.light { + color: $light-bg-light; + } + } + } + + a.Button { + display: block; + padding: $unit * 1.5; + text-align: center; + } +} + #Teams, #Profile { display: flex; height: 100%;