Merge pull request #4 from jedmund/uncap-indicator
Implement interactive uncap indicators
|
|
@ -1,11 +1,18 @@
|
||||||
import React, { useState } from 'react'
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
|
import { useCookies } from 'react-cookie'
|
||||||
import { useModal as useModal } from '~utils/useModal'
|
import { useModal as useModal } from '~utils/useModal'
|
||||||
|
|
||||||
|
import { AxiosResponse } from 'axios'
|
||||||
|
import debounce from 'lodash.debounce'
|
||||||
|
|
||||||
import CharacterUnit from '~components/CharacterUnit'
|
import CharacterUnit from '~components/CharacterUnit'
|
||||||
import SearchModal from '~components/SearchModal'
|
import SearchModal from '~components/SearchModal'
|
||||||
|
|
||||||
|
import api from '~utils/api'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
|
// GridType
|
||||||
export enum GridType {
|
export enum GridType {
|
||||||
Class,
|
Class,
|
||||||
Character,
|
Character,
|
||||||
|
|
@ -13,63 +20,202 @@ export enum GridType {
|
||||||
Summon
|
Summon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Props
|
||||||
interface Props {
|
interface Props {
|
||||||
userId?: string
|
partyId?: string
|
||||||
grid: GridArray<Character>
|
characters: GridArray<GridCharacter>
|
||||||
editable: boolean
|
editable: boolean
|
||||||
exists: boolean
|
createParty: () => Promise<AxiosResponse<any, any>>
|
||||||
onSelect: (type: GridType, character: Character, position: number) => void
|
pushHistory?: (path: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const CharacterGrid = (props: Props) => {
|
const CharacterGrid = (props: Props) => {
|
||||||
const { open, openModal, closeModal } = useModal()
|
// Constants
|
||||||
const [searchPosition, setSearchPosition] = useState(0)
|
|
||||||
|
|
||||||
const numCharacters: number = 5
|
const numCharacters: number = 5
|
||||||
|
|
||||||
function isCharacter(object: Character | Weapon | Summon): object is Character {
|
// Cookies
|
||||||
// There aren't really any unique fields here
|
const [cookies, _] = useCookies(['user'])
|
||||||
return (object as Character).gender !== undefined
|
const headers = (cookies.user != null) ? {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${cookies.user.access_token}`
|
||||||
}
|
}
|
||||||
|
} : {}
|
||||||
|
|
||||||
|
// Set up state for party
|
||||||
|
const [partyId, setPartyId] = useState('')
|
||||||
|
|
||||||
|
// Set up states for Grid data
|
||||||
|
const [characters, setCharacters] = useState<GridArray<GridCharacter>>({})
|
||||||
|
|
||||||
|
// Set up states for Search
|
||||||
|
const { open, openModal, closeModal } = useModal()
|
||||||
|
const [itemPositionForSearch, setItemPositionForSearch] = useState(0)
|
||||||
|
|
||||||
|
// Create a temporary state to store previous character uncap values
|
||||||
|
const [previousUncapValues, setPreviousUncapValues] = useState<{[key: number]: number}>({})
|
||||||
|
|
||||||
|
// Create a state dictionary to store pure objects for Search
|
||||||
|
const [searchGrid, setSearchGrid] = useState<GridArray<Character>>({})
|
||||||
|
|
||||||
|
// Set states from props
|
||||||
|
useEffect(() => {
|
||||||
|
setPartyId(props.partyId || '')
|
||||||
|
setCharacters(props.characters || {})
|
||||||
|
}, [props])
|
||||||
|
|
||||||
|
// Initialize an array of current uncap values for each characters
|
||||||
|
useEffect(() => {
|
||||||
|
let initialPreviousUncapValues: {[key: number]: number} = {}
|
||||||
|
Object.values(props.characters).map(o => initialPreviousUncapValues[o.position] = o.uncap_level)
|
||||||
|
setPreviousUncapValues(initialPreviousUncapValues)
|
||||||
|
}, [props])
|
||||||
|
|
||||||
|
// Update search grid whenever characters are updated
|
||||||
|
useEffect(() => {
|
||||||
|
let newSearchGrid = Object.values(characters).map((o) => o.character)
|
||||||
|
setSearchGrid(newSearchGrid)
|
||||||
|
}, [characters])
|
||||||
|
|
||||||
|
// Methods: Adding an object from search
|
||||||
function openSearchModal(position: number) {
|
function openSearchModal(position: number) {
|
||||||
setSearchPosition(position)
|
setItemPositionForSearch(position)
|
||||||
openModal()
|
openModal()
|
||||||
}
|
}
|
||||||
|
|
||||||
function receiveCharacter(character: Character, position: number) {
|
function receiveCharacterFromSearch(object: Character | Weapon | Summon, position: number) {
|
||||||
props.onSelect(GridType.Character, character, position)
|
const character = object as Character
|
||||||
}
|
|
||||||
|
|
||||||
function sendData(object: Character | Weapon | Summon, position: number) {
|
if (!partyId) {
|
||||||
if (isCharacter(object)) {
|
props.createParty()
|
||||||
receiveCharacter(object, position)
|
.then(response => {
|
||||||
|
const party = response.data.party
|
||||||
|
if (props.pushHistory) props.pushHistory(`/p/${party.shortcode}`)
|
||||||
|
saveCharacter(party.id, character, position)
|
||||||
|
.then(response => storeGridCharacter(response.data.grid_character))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
saveCharacter(partyId, character, position)
|
||||||
|
.then(response => storeGridCharacter(response.data.grid_character))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function saveCharacter(partyId: string, character: Character, position: number) {
|
||||||
|
return await api.endpoints.characters.create({
|
||||||
|
'character': {
|
||||||
|
'party_id': partyId,
|
||||||
|
'character_id': character.id,
|
||||||
|
'position': position,
|
||||||
|
'mainhand': (position == -1),
|
||||||
|
'uncap_level': characterUncapLevel(character)
|
||||||
|
}
|
||||||
|
}, headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
function storeGridCharacter(gridCharacter: GridCharacter) {
|
||||||
|
// Store the grid unit at the correct position
|
||||||
|
let newCharacters = Object.assign({}, characters)
|
||||||
|
newCharacters[gridCharacter.position] = gridCharacter
|
||||||
|
setCharacters(newCharacters)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods: Helpers
|
||||||
|
function characterUncapLevel(character: Character) {
|
||||||
|
let uncapLevel
|
||||||
|
|
||||||
|
if (character.special) {
|
||||||
|
uncapLevel = 3
|
||||||
|
if (character.uncap.ulb) uncapLevel = 5
|
||||||
|
else if (character.uncap.flb) uncapLevel = 4
|
||||||
|
} else {
|
||||||
|
uncapLevel = 4
|
||||||
|
if (character.uncap.ulb) uncapLevel = 6
|
||||||
|
else if (character.uncap.flb) uncapLevel = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
return uncapLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods: Updating uncap level
|
||||||
|
// Note: Saves, but debouncing is not working properly
|
||||||
|
async function saveUncap(id: string, position: number, uncapLevel: number) {
|
||||||
|
storePreviousUncapValue(position)
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (uncapLevel != previousUncapValues[position])
|
||||||
|
await api.updateUncap('weapon', id, uncapLevel)
|
||||||
|
.then(response => { storeGridCharacter(response.data.grid_character) })
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
|
||||||
|
// Revert optimistic UI
|
||||||
|
updateUncapLevel(position, previousUncapValues[position])
|
||||||
|
|
||||||
|
// Remove optimistic key
|
||||||
|
let newPreviousValues = {...previousUncapValues}
|
||||||
|
delete newPreviousValues[position]
|
||||||
|
setPreviousUncapValues(newPreviousValues)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initiateUncapUpdate = useCallback(
|
||||||
|
(id: string, position: number, uncapLevel: number) => {
|
||||||
|
memoizeAction(id, position, uncapLevel)
|
||||||
|
|
||||||
|
// Optimistically update UI
|
||||||
|
updateUncapLevel(position, uncapLevel)
|
||||||
|
}, [previousUncapValues, characters]
|
||||||
|
)
|
||||||
|
|
||||||
|
const memoizeAction = useCallback(
|
||||||
|
(id: string, position: number, uncapLevel: number) => {
|
||||||
|
debouncedAction(id, position, uncapLevel)
|
||||||
|
}, [props]
|
||||||
|
)
|
||||||
|
|
||||||
|
const debouncedAction = useMemo(() =>
|
||||||
|
debounce((id, position, number) => {
|
||||||
|
saveUncap(id, position, number)
|
||||||
|
}, 500), [props, saveUncap]
|
||||||
|
)
|
||||||
|
|
||||||
|
const updateUncapLevel = (position: number, uncapLevel: number) => {
|
||||||
|
let newCharacters = {...characters}
|
||||||
|
newCharacters[position].uncap_level = uncapLevel
|
||||||
|
setCharacters(newCharacters)
|
||||||
|
}
|
||||||
|
|
||||||
|
function storePreviousUncapValue(position: number) {
|
||||||
|
// Save the current value in case of an unexpected result
|
||||||
|
let newPreviousValues = {...previousUncapValues}
|
||||||
|
newPreviousValues[position] = characters[position].uncap_level
|
||||||
|
|
||||||
|
setPreviousUncapValues(newPreviousValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render: JSX components
|
||||||
return (
|
return (
|
||||||
<div className="CharacterGrid">
|
<div className="CharacterGrid">
|
||||||
<ul id="grid_characters">
|
<ul id="grid_characters">
|
||||||
{
|
{Array.from(Array(numCharacters)).map((x, i) => {
|
||||||
Array.from(Array(numCharacters)).map((x, i) => {
|
|
||||||
return (
|
return (
|
||||||
<li key={`grid_unit_${i}`} >
|
<li key={`grid_unit_${i}`} >
|
||||||
<CharacterUnit
|
<CharacterUnit
|
||||||
onClick={() => { openSearchModal(i) }}
|
gridCharacter={props.characters[i]}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
position={i}
|
position={i}
|
||||||
character={props.grid[i]}
|
onClick={() => { openSearchModal(i) }}
|
||||||
|
updateUncap={initiateUncapUpdate}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
{open ? (
|
{open ? (
|
||||||
<SearchModal
|
<SearchModal
|
||||||
grid={props.grid}
|
grid={searchGrid}
|
||||||
close={closeModal}
|
close={closeModal}
|
||||||
send={sendData}
|
send={receiveCharacterFromSearch}
|
||||||
fromPosition={searchPosition}
|
fromPosition={itemPositionForSearch}
|
||||||
object="characters"
|
object="characters"
|
||||||
placeholderText="Search for a character..."
|
placeholderText="Search for a character..."
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
box-shadow: rgba(0, 0, 0, 0.14) 0px 0px 14px;
|
box-shadow: rgba(0, 0, 0, 0.14) 0px 0px 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transform: scale(1.1, 1.1);
|
transform: $scale-tall;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CharacterUnit.filled h3 {
|
.CharacterUnit.filled h3 {
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,16 @@ import React, { useEffect, useState } from 'react'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
|
|
||||||
import UncapIndicator from '~components/UncapIndicator'
|
import UncapIndicator from '~components/UncapIndicator'
|
||||||
|
|
||||||
import PlusIcon from '~public/icons/plus.svg'
|
import PlusIcon from '~public/icons/plus.svg'
|
||||||
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onClick: () => void
|
gridCharacter: GridCharacter | undefined
|
||||||
character: Character | undefined
|
|
||||||
position: number
|
position: number
|
||||||
editable: boolean
|
editable: boolean
|
||||||
|
onClick: () => void
|
||||||
|
updateUncap: (id: string, position: number, uncap: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const CharacterUnit = (props: Props) => {
|
const CharacterUnit = (props: Props) => {
|
||||||
|
|
@ -20,27 +20,32 @@ const CharacterUnit = (props: Props) => {
|
||||||
const classes = classnames({
|
const classes = classnames({
|
||||||
CharacterUnit: true,
|
CharacterUnit: true,
|
||||||
'editable': props.editable,
|
'editable': props.editable,
|
||||||
'filled': (props.character !== undefined)
|
'filled': (props.gridCharacter !== undefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
const character = props.character
|
const gridCharacter = props.gridCharacter
|
||||||
|
const character = gridCharacter?.character
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
generateImageUrl()
|
generateImageUrl()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
function generateImageUrl() {
|
function generateImageUrl() {
|
||||||
let imgSrc = ""
|
let imgSrc = ""
|
||||||
|
|
||||||
if (props.character) {
|
if (props.gridCharacter) {
|
||||||
const character = props.character!
|
const character = props.gridCharacter.character!
|
||||||
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/chara-main/${character.granblue_id}_01.jpg`
|
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/chara-main/${character.granblue_id}_01.jpg`
|
||||||
}
|
}
|
||||||
|
|
||||||
setImageUrl(imgSrc)
|
setImageUrl(imgSrc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function passUncapData(uncap: number) {
|
||||||
|
if (props.gridCharacter)
|
||||||
|
props.updateUncap(props.gridCharacter.id, props.position, uncap)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className={classes}>
|
<div className={classes}>
|
||||||
|
|
@ -48,11 +53,15 @@ const CharacterUnit = (props: Props) => {
|
||||||
<img alt={character?.name.en} className="grid_image" src={imageUrl} />
|
<img alt={character?.name.en} className="grid_image" src={imageUrl} />
|
||||||
{ (props.editable) ? <span className='icon'><PlusIcon /></span> : '' }
|
{ (props.editable) ? <span className='icon'><PlusIcon /></span> : '' }
|
||||||
</div>
|
</div>
|
||||||
|
{ (gridCharacter && character) ?
|
||||||
<UncapIndicator
|
<UncapIndicator
|
||||||
type="character"
|
type="character"
|
||||||
flb={character?.uncap.flb || false}
|
flb={character.uncap.flb || false}
|
||||||
uncapLevel={(character?.rarity == 2) ? 3 : 4}
|
ulb={character.uncap.ulb || false}
|
||||||
/>
|
uncapLevel={gridCharacter.uncap_level}
|
||||||
|
updateUncap={passUncapData}
|
||||||
|
special={character.special}
|
||||||
|
/> : '' }
|
||||||
<h3 className="CharacterName">{character?.name.en}</h3>
|
<h3 className="CharacterName">{character?.name.en}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,13 @@ export enum GridType {
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
interface Props {
|
interface Props {
|
||||||
grid: GridArray<Summon>
|
grid: GridArray<GridSummon>
|
||||||
editable: boolean
|
editable: boolean
|
||||||
exists: boolean
|
exists: boolean
|
||||||
found?: boolean
|
found?: boolean
|
||||||
offset: number
|
offset: number
|
||||||
onClick: (position: number) => void
|
onClick: (position: number) => void
|
||||||
|
updateUncap: (id: string, position: number, uncap: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const ExtraSummons = (props: Props) => {
|
const ExtraSummons = (props: Props) => {
|
||||||
|
|
@ -32,11 +33,12 @@ const ExtraSummons = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<li key={`grid_unit_${i}`} >
|
<li key={`grid_unit_${i}`} >
|
||||||
<SummonUnit
|
<SummonUnit
|
||||||
onClick={() => { props.onClick(props.offset + i) }}
|
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
position={props.offset + i}
|
position={props.offset + i}
|
||||||
unitType={1}
|
unitType={1}
|
||||||
summon={props.grid[props.offset + i]}
|
gridSummon={props.grid[props.offset + i]}
|
||||||
|
onClick={() => { props.onClick(props.offset + i) }}
|
||||||
|
updateUncap={props.updateUncap}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,12 @@ export enum GridType {
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
interface Props {
|
interface Props {
|
||||||
grid: GridArray<Weapon>
|
grid: GridArray<GridWeapon>
|
||||||
editable: boolean
|
editable: boolean
|
||||||
exists: boolean
|
|
||||||
found?: boolean
|
found?: boolean
|
||||||
offset: number
|
offset: number
|
||||||
onClick: (position: number) => void
|
onClick: (position: number) => void
|
||||||
|
updateUncap: (id: string, position: number, uncap: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const ExtraWeapons = (props: Props) => {
|
const ExtraWeapons = (props: Props) => {
|
||||||
|
|
@ -34,10 +34,11 @@ const ExtraWeapons = (props: Props) => {
|
||||||
<li key={`grid_unit_${i}`} >
|
<li key={`grid_unit_${i}`} >
|
||||||
<WeaponUnit
|
<WeaponUnit
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
onClick={() => { props.onClick(props.offset + i)}}
|
|
||||||
position={props.offset + i}
|
position={props.offset + i}
|
||||||
unitType={1}
|
unitType={1}
|
||||||
weapon={props.grid[props.offset + i]}
|
gridWeapon={props.grid[props.offset + i]}
|
||||||
|
onClick={() => { props.onClick(props.offset + i)}}
|
||||||
|
updateUncap={props.updateUncap}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
import React, { ChangeEvent, useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useCookies } from 'react-cookie'
|
import { useCookies } from 'react-cookie'
|
||||||
import api from '~utils/api'
|
|
||||||
|
|
||||||
// UI Elements
|
|
||||||
import PartySegmentedControl from '~components/PartySegmentedControl'
|
import PartySegmentedControl from '~components/PartySegmentedControl'
|
||||||
|
|
||||||
// Grids
|
|
||||||
import WeaponGrid from '~components/WeaponGrid'
|
import WeaponGrid from '~components/WeaponGrid'
|
||||||
import SummonGrid from '~components/SummonGrid'
|
import SummonGrid from '~components/SummonGrid'
|
||||||
import CharacterGrid from '~components/CharacterGrid'
|
import CharacterGrid from '~components/CharacterGrid'
|
||||||
|
|
||||||
|
import api from '~utils/api'
|
||||||
|
import './index.scss'
|
||||||
|
|
||||||
// GridType
|
// GridType
|
||||||
enum GridType {
|
enum GridType {
|
||||||
Class,
|
Class,
|
||||||
|
|
@ -17,96 +16,58 @@ enum GridType {
|
||||||
Weapon,
|
Weapon,
|
||||||
Summon
|
Summon
|
||||||
}
|
}
|
||||||
export { GridType }
|
|
||||||
|
|
||||||
import './index.scss'
|
|
||||||
|
|
||||||
|
// Props
|
||||||
interface Props {
|
interface Props {
|
||||||
partyId?: string
|
partyId?: string
|
||||||
mainWeapon?: Weapon
|
mainWeapon?: GridWeapon
|
||||||
mainSummon?: Summon
|
mainSummon?: GridSummon
|
||||||
friendSummon?: Summon
|
friendSummon?: GridSummon
|
||||||
characters?: GridArray<Character>
|
characters?: GridArray<GridCharacter>
|
||||||
weapons?: GridArray<Weapon>
|
weapons?: GridArray<GridWeapon>
|
||||||
summons?: GridArray<Summon>
|
summons?: GridArray<GridSummon>
|
||||||
extra: boolean
|
extra: boolean
|
||||||
editable: boolean
|
editable: boolean
|
||||||
exists: boolean
|
|
||||||
pushHistory?: (path: string) => void
|
pushHistory?: (path: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const Party = (props: Props) => {
|
const Party = (props: Props) => {
|
||||||
|
// Cookies
|
||||||
const [cookies, _] = useCookies(['user'])
|
const [cookies, _] = useCookies(['user'])
|
||||||
|
|
||||||
const headers = (cookies.user != null) ? {
|
const headers = (cookies.user != null) ? {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${cookies.user.access_token}`
|
'Authorization': `Bearer ${cookies.user.access_token}`
|
||||||
}
|
}
|
||||||
} : {}
|
} : {}
|
||||||
|
|
||||||
// Grid data
|
// Set up states
|
||||||
const [characters, setCharacters] = useState<GridArray<Character>>({})
|
|
||||||
const [weapons, setWeapons] = useState<GridArray<Weapon>>({})
|
|
||||||
const [summons, setSummons] = useState<GridArray<Summon>>({})
|
|
||||||
|
|
||||||
const [mainWeapon, setMainWeapon] = useState<Weapon>()
|
|
||||||
const [mainSummon, setMainSummon] = useState<Summon>()
|
|
||||||
const [friendSummon, setFriendSummon] = useState<Summon>()
|
|
||||||
|
|
||||||
const [extra, setExtra] = useState<boolean>(false)
|
const [extra, setExtra] = useState<boolean>(false)
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setPartyId(props.partyId || '')
|
|
||||||
setMainWeapon(props.mainWeapon)
|
|
||||||
setMainSummon(props.mainSummon)
|
|
||||||
setFriendSummon(props.friendSummon)
|
|
||||||
setCharacters(props.characters || {})
|
|
||||||
setWeapons(props.weapons || {})
|
|
||||||
setSummons(props.summons || {})
|
|
||||||
setExtra(props.extra || false)
|
|
||||||
}, [props.partyId, props.mainWeapon, props.mainSummon, props.friendSummon, props.characters, props.weapons, props.summons, props.extra])
|
|
||||||
|
|
||||||
const weaponGrid = (
|
|
||||||
<WeaponGrid
|
|
||||||
userId={cookies.user ? cookies.user.userId : ''}
|
|
||||||
mainhand={mainWeapon}
|
|
||||||
grid={weapons}
|
|
||||||
editable={props.editable}
|
|
||||||
exists={props.exists}
|
|
||||||
extra={extra}
|
|
||||||
onSelect={itemSelected}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
const summonGrid = (
|
|
||||||
<SummonGrid
|
|
||||||
userId={cookies.user ? cookies.user.userId : ''}
|
|
||||||
main={mainSummon}
|
|
||||||
friend={friendSummon}
|
|
||||||
grid={summons}
|
|
||||||
editable={props.editable}
|
|
||||||
exists={props.exists}
|
|
||||||
onSelect={itemSelected}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
const characterGrid = (
|
|
||||||
<CharacterGrid
|
|
||||||
userId={cookies.user ? cookies.user.userId : ''}
|
|
||||||
grid={characters}
|
|
||||||
editable={props.editable}
|
|
||||||
exists={props.exists}
|
|
||||||
onSelect={itemSelected}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
const [currentTab, setCurrentTab] = useState<GridType>(GridType.Weapon)
|
const [currentTab, setCurrentTab] = useState<GridType>(GridType.Weapon)
|
||||||
const [partyId, setPartyId] = useState('')
|
|
||||||
|
|
||||||
|
// Set states from props
|
||||||
|
useEffect(() => {
|
||||||
|
setExtra(props.extra || false)
|
||||||
|
}, [props])
|
||||||
|
|
||||||
|
// Methods: Creating a new party
|
||||||
|
async function createParty() {
|
||||||
|
let body = {
|
||||||
|
party: {
|
||||||
|
...(cookies.user) && { user_id: cookies.user.user_id },
|
||||||
|
is_extra: extra
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await api.endpoints.parties.create(body, headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods: Updating the party's extra flag
|
||||||
|
// Note: This doesn't save to the server yet.
|
||||||
function checkboxChanged(event: React.ChangeEvent<HTMLInputElement>) {
|
function checkboxChanged(event: React.ChangeEvent<HTMLInputElement>) {
|
||||||
setExtra(event.target.checked)
|
setExtra(event.target.checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Methods: Navigating with segmented control
|
||||||
function segmentClicked(event: React.ChangeEvent<HTMLInputElement>) {
|
function segmentClicked(event: React.ChangeEvent<HTMLInputElement>) {
|
||||||
switch(event.target.value) {
|
switch(event.target.value) {
|
||||||
case 'class':
|
case 'class':
|
||||||
|
|
@ -126,146 +87,8 @@ const Party = (props: Props) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function itemSelected(type: GridType, item: Character | Weapon | Summon, position: number) {
|
// Render: JSX components
|
||||||
if (!partyId) {
|
const navigation = (
|
||||||
createParty()
|
|
||||||
.then(response => {
|
|
||||||
return response.data.party
|
|
||||||
})
|
|
||||||
.then(party => {
|
|
||||||
if (props.pushHistory) {
|
|
||||||
props.pushHistory(`/p/${party.shortcode}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return party.id
|
|
||||||
})
|
|
||||||
.then(partyId => {
|
|
||||||
setPartyId(partyId)
|
|
||||||
saveItem(partyId, type, item, position)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
saveItem(partyId, type, item, position)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createParty() {
|
|
||||||
const body = (!cookies.user) ? {
|
|
||||||
party: {
|
|
||||||
is_extra: extra
|
|
||||||
}
|
|
||||||
} : {
|
|
||||||
party: {
|
|
||||||
user_id: cookies.user.userId,
|
|
||||||
is_extra: extra
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return await api.endpoints.parties.create(body, headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveItem(partyId: string, type: GridType, item: Character | Weapon | Summon, position: number) {
|
|
||||||
switch(type) {
|
|
||||||
case GridType.Class:
|
|
||||||
saveClass()
|
|
||||||
break
|
|
||||||
case GridType.Character:
|
|
||||||
const character = item as Character
|
|
||||||
saveCharacter(character, position, partyId)
|
|
||||||
.then(() => {
|
|
||||||
storeCharacter(character, position)
|
|
||||||
})
|
|
||||||
break
|
|
||||||
case GridType.Weapon:
|
|
||||||
const weapon = item as Weapon
|
|
||||||
saveWeapon(weapon, position, partyId)
|
|
||||||
.then(() => {
|
|
||||||
storeWeapon(weapon, position)
|
|
||||||
})
|
|
||||||
break
|
|
||||||
case GridType.Summon:
|
|
||||||
const summon = item as Summon
|
|
||||||
saveSummon(summon, position, partyId)
|
|
||||||
.then(() => {
|
|
||||||
storeSummon(summon, position)
|
|
||||||
})
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Weapons
|
|
||||||
function storeWeapon(weapon: Weapon, position: number) {
|
|
||||||
if (position == -1) {
|
|
||||||
setMainWeapon(weapon)
|
|
||||||
} else {
|
|
||||||
// Store the grid unit weapon at the correct position
|
|
||||||
let newWeapons = Object.assign({}, weapons)
|
|
||||||
newWeapons[position] = weapon
|
|
||||||
setWeapons(newWeapons)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function saveWeapon(weapon: Weapon, position: number, party: string) {
|
|
||||||
await api.endpoints.weapons.create({
|
|
||||||
'weapon': {
|
|
||||||
'party_id': party,
|
|
||||||
'weapon_id': weapon.id,
|
|
||||||
'position': position,
|
|
||||||
'mainhand': (position == -1)
|
|
||||||
}
|
|
||||||
}, headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Summons
|
|
||||||
function storeSummon(summon: Summon, position: number) {
|
|
||||||
if (position == -1) {
|
|
||||||
setMainSummon(summon)
|
|
||||||
} else if (position == 6) {
|
|
||||||
setFriendSummon(summon)
|
|
||||||
} else {
|
|
||||||
// Store the grid unit summon at the correct position
|
|
||||||
let newSummons = Object.assign({}, summons)
|
|
||||||
newSummons[position] = summon
|
|
||||||
setSummons(newSummons)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function saveSummon(summon: Summon, position: number, party: string) {
|
|
||||||
await api.endpoints.summons.create({
|
|
||||||
'summon': {
|
|
||||||
'party_id': party,
|
|
||||||
'summon_id': summon.id,
|
|
||||||
'position': position,
|
|
||||||
'main': (position == -1),
|
|
||||||
'friend': (position == 6)
|
|
||||||
}
|
|
||||||
}, headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Character
|
|
||||||
function storeCharacter(character: Character, position: number) {
|
|
||||||
// Store the grid unit character at the correct position
|
|
||||||
let newCharacters = Object.assign({}, characters)
|
|
||||||
newCharacters[position] = character
|
|
||||||
setCharacters(newCharacters)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function saveCharacter(character: Character, position: number, party: string) {
|
|
||||||
await api.endpoints.characters.create({
|
|
||||||
'character': {
|
|
||||||
'party_id': party,
|
|
||||||
'character_id': character.id,
|
|
||||||
'position': position
|
|
||||||
}
|
|
||||||
}, headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Class
|
|
||||||
function saveClass() {
|
|
||||||
// TODO: Implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<PartySegmentedControl
|
<PartySegmentedControl
|
||||||
extra={extra}
|
extra={extra}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
|
|
@ -273,9 +96,43 @@ const Party = (props: Props) => {
|
||||||
onClick={segmentClicked}
|
onClick={segmentClicked}
|
||||||
onCheckboxChange={checkboxChanged}
|
onCheckboxChange={checkboxChanged}
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
{
|
const weaponGrid = (
|
||||||
(() => {
|
<WeaponGrid
|
||||||
|
partyId={props.partyId}
|
||||||
|
mainhand={props.mainWeapon}
|
||||||
|
weapons={props.weapons || {}}
|
||||||
|
extra={extra}
|
||||||
|
editable={props.editable}
|
||||||
|
createParty={createParty}
|
||||||
|
pushHistory={props.pushHistory}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
const summonGrid = (
|
||||||
|
<SummonGrid
|
||||||
|
partyId={props.partyId}
|
||||||
|
mainSummon={props.mainSummon}
|
||||||
|
friendSummon={props.friendSummon}
|
||||||
|
summons={props.summons || {}}
|
||||||
|
editable={props.editable}
|
||||||
|
createParty={createParty}
|
||||||
|
pushHistory={props.pushHistory}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
const characterGrid = (
|
||||||
|
<CharacterGrid
|
||||||
|
partyId={props.partyId}
|
||||||
|
characters={props.characters || {}}
|
||||||
|
editable={props.editable}
|
||||||
|
createParty={createParty}
|
||||||
|
pushHistory={props.pushHistory}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
const currentGrid = () => {
|
||||||
switch(currentTab) {
|
switch(currentTab) {
|
||||||
case GridType.Character:
|
case GridType.Character:
|
||||||
return characterGrid
|
return characterGrid
|
||||||
|
|
@ -284,8 +141,12 @@ const Party = (props: Props) => {
|
||||||
case GridType.Summon:
|
case GridType.Summon:
|
||||||
return summonGrid
|
return summonGrid
|
||||||
}
|
}
|
||||||
})()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{ navigation }
|
||||||
|
{ currentGrid() }
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
import React, { useState } from 'react'
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
|
import { useCookies } from 'react-cookie'
|
||||||
import { useModal as useModal } from '~utils/useModal'
|
import { useModal as useModal } from '~utils/useModal'
|
||||||
|
|
||||||
import SearchModal from '~components/SearchModal'
|
import { AxiosResponse } from 'axios'
|
||||||
import ExtraSummons from '~components/ExtraSummons'
|
import debounce from 'lodash.debounce'
|
||||||
import SummonUnit from '~components/SummonUnit'
|
|
||||||
|
|
||||||
|
import SearchModal from '~components/SearchModal'
|
||||||
|
import SummonUnit from '~components/SummonUnit'
|
||||||
|
import ExtraSummons from '~components/ExtraSummons'
|
||||||
|
|
||||||
|
import api from '~utils/api'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
// GridType
|
// GridType
|
||||||
|
|
@ -17,106 +23,262 @@ export enum GridType {
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
interface Props {
|
interface Props {
|
||||||
userId?: string
|
|
||||||
partyId?: string
|
partyId?: string
|
||||||
main?: Summon | undefined
|
mainSummon: GridSummon | undefined
|
||||||
friend?: Summon | undefined
|
friendSummon: GridSummon | undefined
|
||||||
grid: GridArray<Summon>
|
summons: GridArray<GridSummon>
|
||||||
editable: boolean
|
editable: boolean
|
||||||
exists: boolean
|
createParty: () => Promise<AxiosResponse<any, any>>
|
||||||
found?: boolean
|
pushHistory?: (path: string) => void
|
||||||
onSelect: (type: GridType, summon: Summon, position: number) => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const SummonGrid = (props: Props) => {
|
const SummonGrid = (props: Props) => {
|
||||||
const { open, openModal, closeModal } = useModal()
|
// Constants
|
||||||
const [searchPosition, setSearchPosition] = useState(0)
|
|
||||||
|
|
||||||
const numSummons: number = 4
|
const numSummons: number = 4
|
||||||
|
|
||||||
|
// Cookies
|
||||||
|
const [cookies, _] = useCookies(['user'])
|
||||||
|
const headers = (cookies.user != null) ? {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${cookies.user.access_token}`
|
||||||
|
}
|
||||||
|
} : {}
|
||||||
|
|
||||||
|
// Set up state for party
|
||||||
|
const [partyId, setPartyId] = useState('')
|
||||||
|
|
||||||
|
// Set up states for Grid data
|
||||||
|
const [summons, setSummons] = useState<GridArray<GridSummon>>({})
|
||||||
|
const [mainSummon, setMainSummon] = useState<GridSummon>()
|
||||||
|
const [friendSummon, setFriendSummon] = useState<GridSummon>()
|
||||||
|
|
||||||
|
// Set up states for Search
|
||||||
|
const { open, openModal, closeModal } = useModal()
|
||||||
|
const [itemPositionForSearch, setItemPositionForSearch] = useState(0)
|
||||||
|
|
||||||
|
// Create a temporary state to store previous weapon uncap value
|
||||||
|
const [previousUncapValues, setPreviousUncapValues] = useState<{[key: number]: number}>({})
|
||||||
|
|
||||||
|
// Create a state dictionary to store pure objects for Search
|
||||||
|
const [searchGrid, setSearchGrid] = useState<GridArray<Summon>>({})
|
||||||
|
|
||||||
|
// Initialize an array of current uncap values for each summon
|
||||||
|
useEffect(() => {
|
||||||
|
let initialPreviousUncapValues: {[key: number]: number} = {}
|
||||||
|
if (props.mainSummon) initialPreviousUncapValues[-1] = props.mainSummon.uncap_level
|
||||||
|
if (props.friendSummon) initialPreviousUncapValues[6] = props.friendSummon.uncap_level
|
||||||
|
Object.values(props.summons).map(o => initialPreviousUncapValues[o.position] = o.uncap_level)
|
||||||
|
setPreviousUncapValues(initialPreviousUncapValues)
|
||||||
|
}, [props])
|
||||||
|
|
||||||
|
// Set states from props
|
||||||
|
useEffect(() => {
|
||||||
|
setSummons(props.summons || {})
|
||||||
|
setMainSummon(props.mainSummon)
|
||||||
|
setFriendSummon(props.friendSummon)
|
||||||
|
}, [props])
|
||||||
|
|
||||||
|
// Update search grid whenever any summon is updated
|
||||||
|
useEffect(() => {
|
||||||
|
let newSearchGrid = Object.values(summons).map((o) => o.summon)
|
||||||
|
|
||||||
|
if (mainSummon)
|
||||||
|
newSearchGrid.unshift(mainSummon.summon)
|
||||||
|
|
||||||
|
if (friendSummon)
|
||||||
|
newSearchGrid.unshift(friendSummon.summon)
|
||||||
|
|
||||||
|
setSearchGrid(newSearchGrid)
|
||||||
|
}, [summons, mainSummon, friendSummon])
|
||||||
|
|
||||||
|
// Methods: Adding an object from search
|
||||||
function openSearchModal(position: number) {
|
function openSearchModal(position: number) {
|
||||||
setSearchPosition(position)
|
setItemPositionForSearch(position)
|
||||||
openModal()
|
openModal()
|
||||||
}
|
}
|
||||||
|
|
||||||
function receiveSummon(summon: Summon, position: number) {
|
function receiveSummonFromSearch(object: Character | Weapon | Summon, position: number) {
|
||||||
props.onSelect(GridType.Summon, summon, position)
|
const summon = object as Summon
|
||||||
}
|
|
||||||
|
|
||||||
function sendData(object: Character | Weapon | Summon, position: number) {
|
if (!partyId) {
|
||||||
if (isSummon(object)) {
|
props.createParty()
|
||||||
receiveSummon(object, position)
|
.then(response => {
|
||||||
|
const party = response.data.party
|
||||||
|
if (props.pushHistory) props.pushHistory(`/p/${party.shortcode}`)
|
||||||
|
saveSummon(party.id, summon, position)
|
||||||
|
.then(response => storeGridSummon(response.data.grid_summon))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
saveSummon(partyId, summon, position)
|
||||||
|
.then(response => storeGridSummon(response.data.grid_summon))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSummon(object: Character | Weapon | Summon): object is Summon {
|
async function saveSummon(partyId: string, summon: Summon, position: number) {
|
||||||
// There aren't really any unique fields here
|
let uncapLevel = 3
|
||||||
return (object as Summon).granblue_id !== undefined
|
if (summon.uncap.ulb) uncapLevel = 5
|
||||||
|
else if (summon.uncap.flb) uncapLevel = 4
|
||||||
|
|
||||||
|
return await api.endpoints.summons.create({
|
||||||
|
'summon': {
|
||||||
|
'party_id': partyId,
|
||||||
|
'summon_id': summon.id,
|
||||||
|
'position': position,
|
||||||
|
'main': (position == -1),
|
||||||
|
'friend': (position == 6),
|
||||||
|
'uncap_level': uncapLevel
|
||||||
|
}
|
||||||
|
}, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
function storeGridSummon(gridSummon: GridSummon) {
|
||||||
<div>
|
if (gridSummon.position == -1) {
|
||||||
<div className="SummonGrid">
|
setMainSummon(gridSummon)
|
||||||
|
} else if (gridSummon.position == 6) {
|
||||||
|
setFriendSummon(gridSummon)
|
||||||
|
} else {
|
||||||
|
// Store the grid unit at the correct position
|
||||||
|
let newSummons = Object.assign({}, summons)
|
||||||
|
newSummons[gridSummon.position] = gridSummon
|
||||||
|
setSummons(newSummons)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods: Updating uncap level
|
||||||
|
// Note: Saves, but debouncing is not working properly
|
||||||
|
async function saveUncap(id: string, position: number, uncapLevel: number) {
|
||||||
|
storePreviousUncapValue(position)
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (uncapLevel != previousUncapValues[position])
|
||||||
|
await api.updateUncap('summon', id, uncapLevel)
|
||||||
|
.then(response => { storeGridSummon(response.data.grid_summon) })
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
|
||||||
|
// Revert optimistic UI
|
||||||
|
updateUncapLevel(position, previousUncapValues[position])
|
||||||
|
|
||||||
|
// Remove optimistic key
|
||||||
|
let newPreviousValues = {...previousUncapValues}
|
||||||
|
delete newPreviousValues[position]
|
||||||
|
setPreviousUncapValues(newPreviousValues)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initiateUncapUpdate = useCallback(
|
||||||
|
(id: string, position: number, uncapLevel: number) => {
|
||||||
|
memoizeAction(id, position, uncapLevel)
|
||||||
|
|
||||||
|
// Optimistically update UI
|
||||||
|
updateUncapLevel(position, uncapLevel)
|
||||||
|
}, [previousUncapValues, summons]
|
||||||
|
)
|
||||||
|
|
||||||
|
const memoizeAction = useCallback(
|
||||||
|
(id: string, position: number, uncapLevel: number) => {
|
||||||
|
debouncedAction(id, position, uncapLevel)
|
||||||
|
}, [props]
|
||||||
|
)
|
||||||
|
|
||||||
|
const debouncedAction = useMemo(() =>
|
||||||
|
debounce((id, position, number) => {
|
||||||
|
saveUncap(id, position, number)
|
||||||
|
}, 500), [props, saveUncap]
|
||||||
|
)
|
||||||
|
|
||||||
|
const updateUncapLevel = (position: number, uncapLevel: number) => {
|
||||||
|
let newSummons = Object.assign({}, summons)
|
||||||
|
newSummons[position].uncap_level = uncapLevel
|
||||||
|
setSummons(newSummons)
|
||||||
|
}
|
||||||
|
|
||||||
|
function storePreviousUncapValue(position: number) {
|
||||||
|
// Save the current value in case of an unexpected result
|
||||||
|
let newPreviousValues = {...previousUncapValues}
|
||||||
|
|
||||||
|
if (mainSummon && position == -1) newPreviousValues[position] = mainSummon.uncap_level
|
||||||
|
else if (friendSummon && position == 6) newPreviousValues[position] = friendSummon.uncap_level
|
||||||
|
else newPreviousValues[position] = summons[position].uncap_level
|
||||||
|
|
||||||
|
setPreviousUncapValues(newPreviousValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render: JSX components
|
||||||
|
const mainSummonElement = (
|
||||||
<div className="LabeledUnit">
|
<div className="LabeledUnit">
|
||||||
<div className="Label">Main Summon</div>
|
<div className="Label">Main Summon</div>
|
||||||
<SummonUnit
|
<SummonUnit
|
||||||
onClick={() => { openSearchModal(0) }}
|
gridSummon={props.mainSummon}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
key="grid_main_summon"
|
key="grid_main_summon"
|
||||||
position={-1}
|
position={-1}
|
||||||
unitType={0}
|
unitType={0}
|
||||||
summon={props.main}
|
onClick={() => { openSearchModal(-1) }}
|
||||||
|
updateUncap={initiateUncapUpdate}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
const friendSummonElement = (
|
||||||
<div className="LabeledUnit">
|
<div className="LabeledUnit">
|
||||||
<div className="Label">Friend Summon</div>
|
<div className="Label">Friend Summon</div>
|
||||||
<SummonUnit
|
<SummonUnit
|
||||||
onClick={() => { openSearchModal(6) }}
|
gridSummon={props.friendSummon}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
key="grid_friend_summon"
|
key="grid_friend_summon"
|
||||||
position={6}
|
position={6}
|
||||||
unitType={2}
|
unitType={2}
|
||||||
summon={props.friend}
|
onClick={() => { openSearchModal(6) }}
|
||||||
|
updateUncap={initiateUncapUpdate}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
)
|
||||||
|
const summonGridElement = (
|
||||||
<div id="LabeledGrid">
|
<div id="LabeledGrid">
|
||||||
<div className="Label">Summons</div>
|
<div className="Label">Summons</div>
|
||||||
<ul id="grid_summons">
|
<ul id="grid_summons">
|
||||||
{
|
{Array.from(Array(numSummons)).map((x, i) => {
|
||||||
Array.from(Array(numSummons)).map((x, i) => {
|
return (<li key={`grid_unit_${i}`} >
|
||||||
return (
|
|
||||||
<li key={`grid_unit_${i}`} >
|
|
||||||
<SummonUnit
|
<SummonUnit
|
||||||
onClick={() => { openSearchModal(i) }}
|
gridSummon={props.summons[i]}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
position={i}
|
position={i}
|
||||||
unitType={1}
|
unitType={1}
|
||||||
summon={props.grid[i]}
|
onClick={() => { openSearchModal(i) }}
|
||||||
|
updateUncap={initiateUncapUpdate}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>)
|
||||||
)
|
})}
|
||||||
})
|
|
||||||
}
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
|
const subAuraSummonElement = (
|
||||||
<ExtraSummons
|
<ExtraSummons
|
||||||
onClick={openSearchModal}
|
grid={props.summons}
|
||||||
grid={props.grid}
|
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
exists={false}
|
exists={false}
|
||||||
offset={numSummons}
|
offset={numSummons}
|
||||||
|
onClick={openSearchModal}
|
||||||
|
updateUncap={initiateUncapUpdate}
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="SummonGrid">
|
||||||
|
{ mainSummonElement }
|
||||||
|
{ friendSummonElement }
|
||||||
|
{ summonGridElement }
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{ subAuraSummonElement }
|
||||||
|
|
||||||
{open ? (
|
{open ? (
|
||||||
<SearchModal
|
<SearchModal
|
||||||
grid={props.grid}
|
grid={searchGrid}
|
||||||
close={closeModal}
|
close={closeModal}
|
||||||
send={sendData}
|
send={receiveSummonFromSearch}
|
||||||
fromPosition={searchPosition}
|
fromPosition={itemPositionForSearch}
|
||||||
object="summons"
|
object="summons"
|
||||||
placeholderText="Search for a summon..."
|
placeholderText="Search for a summon..."
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,12 @@
|
||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
box-shadow: rgba(0, 0, 0, 0.14) 0px 0px 14px;
|
box-shadow: rgba(0, 0, 0, 0.14) 0px 0px 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transform: scale(1.1, 1.1);
|
transform: $scale-wide;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.main.editable .SummonImage:hover,
|
||||||
|
&.friend.editable .SummonImage:hover {
|
||||||
|
transform: $scale-tall;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.filled h3 {
|
&.filled h3 {
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
|
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
|
|
||||||
import UncapIndicator from '~components/UncapIndicator'
|
import UncapIndicator from '~components/UncapIndicator'
|
||||||
|
|
||||||
import PlusIcon from '~public/icons/plus.svg'
|
import PlusIcon from '~public/icons/plus.svg'
|
||||||
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onClick: () => void
|
onClick: () => void
|
||||||
summon: Summon | undefined
|
updateUncap: (id: string, position: number, uncap: number) => void
|
||||||
|
gridSummon: GridSummon | undefined
|
||||||
position: number
|
position: number
|
||||||
editable: boolean
|
editable: boolean
|
||||||
unitType: 0 | 1 | 2
|
unitType: 0 | 1 | 2
|
||||||
|
|
@ -25,10 +24,11 @@ const SummonUnit = (props: Props) => {
|
||||||
'grid': props.unitType == 1,
|
'grid': props.unitType == 1,
|
||||||
'friend': props.unitType == 2,
|
'friend': props.unitType == 2,
|
||||||
'editable': props.editable,
|
'editable': props.editable,
|
||||||
'filled': (props.summon !== undefined)
|
'filled': (props.gridSummon !== undefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
const summon = props.summon
|
const gridSummon = props.gridSummon
|
||||||
|
const summon = gridSummon?.summon
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
generateImageUrl()
|
generateImageUrl()
|
||||||
|
|
@ -36,8 +36,8 @@ const SummonUnit = (props: Props) => {
|
||||||
|
|
||||||
function generateImageUrl() {
|
function generateImageUrl() {
|
||||||
let imgSrc = ""
|
let imgSrc = ""
|
||||||
if (props.summon) {
|
if (props.gridSummon) {
|
||||||
const summon = props.summon!
|
const summon = props.gridSummon.summon!
|
||||||
|
|
||||||
// Generate the correct source for the summon
|
// Generate the correct source for the summon
|
||||||
if (props.unitType == 0 || props.unitType == 2)
|
if (props.unitType == 0 || props.unitType == 2)
|
||||||
|
|
@ -49,6 +49,11 @@ const SummonUnit = (props: Props) => {
|
||||||
setImageUrl(imgSrc)
|
setImageUrl(imgSrc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function passUncapData(uncap: number) {
|
||||||
|
if (props.gridSummon)
|
||||||
|
props.updateUncap(props.gridSummon.id, uncap)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className={classes}>
|
<div className={classes}>
|
||||||
|
|
@ -56,12 +61,15 @@ const SummonUnit = (props: Props) => {
|
||||||
<img alt={summon?.name.en} className="grid_image" src={imageUrl} />
|
<img alt={summon?.name.en} className="grid_image" src={imageUrl} />
|
||||||
{ (props.editable) ? <span className='icon'><PlusIcon /></span> : '' }
|
{ (props.editable) ? <span className='icon'><PlusIcon /></span> : '' }
|
||||||
</div>
|
</div>
|
||||||
|
{ (gridSummon) ?
|
||||||
<UncapIndicator
|
<UncapIndicator
|
||||||
type="summon"
|
type="summon"
|
||||||
ulb={summon?.uncap.ulb || false}
|
ulb={summon?.uncap.ulb || false}
|
||||||
flb={summon?.uncap.flb || false}
|
flb={summon?.uncap.flb || false}
|
||||||
uncapLevel={3}
|
uncapLevel={gridSummon?.uncap_level}
|
||||||
/>
|
updateUncap={passUncapData}
|
||||||
|
special={false}
|
||||||
|
/> : '' }
|
||||||
<h3 className="SummonName">{summon?.name.en}</h3>
|
<h3 className="SummonName">{summon?.name.en}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,19 @@ const ToggleSwitch: React.FC<Props> = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<div className="toggle-switch">
|
<div className="toggle-switch">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
|
||||||
checked={props.checked}
|
|
||||||
disabled={!props.editable}
|
|
||||||
className="toggle-switch-checkbox"
|
className="toggle-switch-checkbox"
|
||||||
name={props.name}
|
name={props.name}
|
||||||
id={props.name}
|
id={props.name}
|
||||||
|
type="checkbox"
|
||||||
|
checked={props.checked}
|
||||||
|
disabled={!props.editable}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
/>
|
/>
|
||||||
<label className="toggle-switch-label" htmlFor={props.name}>
|
<label className="toggle-switch-label" htmlFor={props.name}>
|
||||||
<span className="toggle-switch-switch" />
|
<span className="toggle-switch-switch" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ToggleSwitch
|
export default ToggleSwitch
|
||||||
|
|
@ -7,4 +7,8 @@
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,27 +1,43 @@
|
||||||
import React from 'react'
|
import React, { useEffect, useRef, useState } from 'react'
|
||||||
import classnames from 'classnames'
|
|
||||||
import UncapStar from '~components/UncapStar'
|
import UncapStar from '~components/UncapStar'
|
||||||
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
type: 'character' | 'weapon' | 'summon'
|
type: 'character' | 'weapon' | 'summon'
|
||||||
rarity?: number
|
rarity?: number
|
||||||
uncapLevel: number
|
uncapLevel: number
|
||||||
flb: boolean
|
flb: boolean
|
||||||
ulb?: boolean
|
ulb: boolean
|
||||||
|
special: boolean
|
||||||
|
updateUncap: (uncap: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const UncapIndicator = (props: Props) => {
|
const UncapIndicator = (props: Props) => {
|
||||||
|
const [uncap, setUncap] = useState(props.uncapLevel)
|
||||||
|
|
||||||
|
const numStars = setNumStars()
|
||||||
|
function setNumStars() {
|
||||||
let numStars
|
let numStars
|
||||||
|
|
||||||
if (props.type === 'character') {
|
if (props.type === 'character') {
|
||||||
if (props.flb) {
|
if (props.special) {
|
||||||
|
if (props.ulb) {
|
||||||
|
numStars = 5
|
||||||
|
} else if (props.flb) {
|
||||||
|
numStars = 4
|
||||||
|
} else {
|
||||||
|
numStars = 3
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (props.ulb) {
|
||||||
|
numStars = 6
|
||||||
|
} else if (props.flb) {
|
||||||
numStars = 5
|
numStars = 5
|
||||||
} else {
|
} else {
|
||||||
numStars = 4
|
numStars = 4
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (props.ulb) {
|
if (props.ulb) {
|
||||||
numStars = 5
|
numStars = 5
|
||||||
|
|
@ -32,15 +48,47 @@ const UncapIndicator = (props: Props) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return numStars
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleStar(index: number, empty: boolean) {
|
||||||
|
if (empty) props.updateUncap(index + 1)
|
||||||
|
else props.updateUncap(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
const transcendence = (i: number) => {
|
||||||
|
return <UncapStar ulb={true} empty={i >= props.uncapLevel} key={`star_${i}`} index={i} onClick={toggleStar} />
|
||||||
|
}
|
||||||
|
|
||||||
|
const ulb = (i: number) => {
|
||||||
|
return <UncapStar ulb={true} empty={i >= props.uncapLevel} key={`star_${i}`} index={i} onClick={toggleStar} />
|
||||||
|
}
|
||||||
|
|
||||||
|
const flb = (i: number) => {
|
||||||
|
return <UncapStar flb={true} empty={i >= props.uncapLevel} key={`star_${i}`} index={i} onClick={toggleStar} />
|
||||||
|
}
|
||||||
|
|
||||||
|
const mlb = (i: number) => {
|
||||||
|
// console.log("MLB; Number of stars:", props.uncapLevel)
|
||||||
|
return <UncapStar empty={i >= props.uncapLevel} key={`star_${i}`} index={i} onClick={toggleStar} />
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ul className="UncapIndicator">
|
<ul className="UncapIndicator">
|
||||||
{
|
{
|
||||||
Array.from(Array(numStars)).map((x, i) => {
|
Array.from(Array(numStars)).map((x, i) => {
|
||||||
if (props.type === 'character' && i > 3 ||
|
if (props.type === 'character' && i > 4) {
|
||||||
|
if (props.special)
|
||||||
|
return ulb(i)
|
||||||
|
else
|
||||||
|
return transcendence(i)
|
||||||
|
} else if (
|
||||||
|
props.special && props.type === 'character' && i == 3 ||
|
||||||
|
props.type === 'character' && i == 4 ||
|
||||||
props.type !== 'character' && i > 2) {
|
props.type !== 'character' && i > 2) {
|
||||||
return <UncapStar uncap={true} key={`star_${i}`} />
|
return flb(i)
|
||||||
} else {
|
} else {
|
||||||
return <UncapStar uncap={false} key={`star_${i}`} />
|
return mlb(i)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,55 @@
|
||||||
.UncapStar {
|
.UncapStar {
|
||||||
color: #FFA15E;
|
background-repeat: no-repeat;
|
||||||
|
background-size: 18px 18px;
|
||||||
|
display: block;
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.UncapStar.uncap {
|
&.empty,
|
||||||
color: #65DAFF;
|
&.empty.mlb,
|
||||||
|
&.empty.flb,
|
||||||
|
&.empty.ulb,
|
||||||
|
&.empty.special {
|
||||||
|
background: url('/icons/uncap/empty.svg');
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: url('/icons/uncap/empty-hover.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mlb {
|
||||||
|
background: url('/icons/uncap/yellow.svg');
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: url('/icons/uncap/yellow-hover.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.special {
|
||||||
|
background: url('/icons/uncap/red.svg');
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: url('/icons/uncap/red-hover.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.flb {
|
||||||
|
background: url('/icons/uncap/blue.svg');
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: url('/icons/uncap/blue-hover.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ulb {
|
||||||
|
background: url('/icons/uncap/purple.svg');
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: url('/icons/uncap/purple-hover.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,18 +4,39 @@ import classnames from 'classnames'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
uncap: boolean
|
empty: boolean
|
||||||
|
special: boolean
|
||||||
|
flb: boolean
|
||||||
|
ulb: boolean
|
||||||
|
index: number
|
||||||
|
onClick: (index: number, empty: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const UncapStar = (props: Props) => {
|
const UncapStar = (props: Props) => {
|
||||||
const classes = classnames({
|
const classes = classnames({
|
||||||
UncapStar: true,
|
UncapStar: true,
|
||||||
'uncap': props.uncap
|
'empty': props.empty,
|
||||||
|
'special': props.special,
|
||||||
|
'mlb': !props.special,
|
||||||
|
'flb': props.flb,
|
||||||
|
'ulb': props.ulb
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function clicked() {
|
||||||
|
props.onClick(props.index, props.empty)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li className={classes}><img alt="" src="/icons/star.svg" /></li>
|
<li className={classes} onClick={clicked}></li>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UncapStar.defaultProps = {
|
||||||
|
empty: false,
|
||||||
|
special: false,
|
||||||
|
flb: false,
|
||||||
|
ulb: false
|
||||||
|
}
|
||||||
|
|
||||||
export default UncapStar
|
export default UncapStar
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
import React, { useState } from 'react'
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
|
import { useCookies } from 'react-cookie'
|
||||||
import { useModal as useModal } from '~utils/useModal'
|
import { useModal as useModal } from '~utils/useModal'
|
||||||
|
|
||||||
|
import { AxiosResponse } from 'axios'
|
||||||
|
import debounce from 'lodash.debounce'
|
||||||
|
|
||||||
import SearchModal from '~components/SearchModal'
|
import SearchModal from '~components/SearchModal'
|
||||||
import WeaponUnit from '~components/WeaponUnit'
|
import WeaponUnit from '~components/WeaponUnit'
|
||||||
import ExtraWeapons from '~components/ExtraWeapons'
|
import ExtraWeapons from '~components/ExtraWeapons'
|
||||||
|
|
||||||
|
import api from '~utils/api'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
// GridType
|
// GridType
|
||||||
|
|
@ -17,95 +23,235 @@ export enum GridType {
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
interface Props {
|
interface Props {
|
||||||
userId?: string
|
|
||||||
partyId?: string
|
partyId?: string
|
||||||
mainhand?: Weapon | undefined
|
mainhand: GridWeapon | undefined
|
||||||
grid: GridArray<Weapon>
|
weapons: GridArray<GridWeapon>
|
||||||
extra: boolean
|
extra: boolean
|
||||||
editable: boolean
|
editable: boolean
|
||||||
exists: boolean
|
createParty: () => Promise<AxiosResponse<any, any>>
|
||||||
found?: boolean
|
pushHistory?: (path: string) => void
|
||||||
onSelect: (type: GridType, weapon: Weapon, position: number) => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const WeaponGrid = (props: Props) => {
|
const WeaponGrid = (props: Props) => {
|
||||||
const { open, openModal, closeModal } = useModal()
|
// Constants
|
||||||
const [searchPosition, setSearchPosition] = useState(0)
|
|
||||||
|
|
||||||
const numWeapons: number = 9
|
const numWeapons: number = 9
|
||||||
|
|
||||||
const extraGrid = (
|
// Cookies
|
||||||
<ExtraWeapons
|
const [cookies, _] = useCookies(['user'])
|
||||||
grid={props.grid}
|
const headers = (cookies.user != null) ? {
|
||||||
editable={props.editable}
|
headers: {
|
||||||
exists={false}
|
'Authorization': `Bearer ${cookies.user.access_token}`
|
||||||
offset={numWeapons}
|
|
||||||
onClick={openSearchModal}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
function receiveWeapon(weapon: Weapon, position: number) {
|
|
||||||
props.onSelect(GridType.Weapon, weapon, position)
|
|
||||||
}
|
}
|
||||||
|
} : {}
|
||||||
|
|
||||||
function sendData(object: Character | Weapon | Summon, position: number) {
|
// Set up state for party
|
||||||
if (isWeapon(object)) {
|
const [partyId, setPartyId] = useState('')
|
||||||
receiveWeapon(object, position)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isWeapon(object: Character | Weapon | Summon): object is Weapon {
|
// Set up states for Grid data
|
||||||
return (object as Weapon).proficiency !== undefined
|
const [weapons, setWeapons] = useState<GridArray<GridWeapon>>({})
|
||||||
}
|
const [mainWeapon, setMainWeapon] = useState<GridWeapon>()
|
||||||
|
|
||||||
|
// Set up states for Search
|
||||||
|
const { open, openModal, closeModal } = useModal()
|
||||||
|
const [itemPositionForSearch, setItemPositionForSearch] = useState(0)
|
||||||
|
|
||||||
|
// Create a temporary state to store previous weapon uncap values
|
||||||
|
const [previousUncapValues, setPreviousUncapValues] = useState<{[key: number]: number}>({})
|
||||||
|
|
||||||
|
// Create a state dictionary to store pure objects for Search
|
||||||
|
const [searchGrid, setSearchGrid] = useState<GridArray<Weapon>>({})
|
||||||
|
|
||||||
|
// Set states from props
|
||||||
|
useEffect(() => {
|
||||||
|
setPartyId(props.partyId || '')
|
||||||
|
setWeapons(props.weapons || {})
|
||||||
|
setMainWeapon(props.mainhand)
|
||||||
|
}, [props])
|
||||||
|
|
||||||
|
// Initialize an array of current uncap values for each weapon
|
||||||
|
useEffect(() => {
|
||||||
|
let initialPreviousUncapValues: {[key: number]: number} = {}
|
||||||
|
if (props.mainhand) initialPreviousUncapValues[-1] = props.mainhand.uncap_level
|
||||||
|
Object.values(props.weapons).map(o => initialPreviousUncapValues[o.position] = o.uncap_level)
|
||||||
|
setPreviousUncapValues(initialPreviousUncapValues)
|
||||||
|
}, [props])
|
||||||
|
|
||||||
|
// Update search grid whenever weapons or the mainhand are updated
|
||||||
|
useEffect(() => {
|
||||||
|
let newSearchGrid = Object.values(weapons).map((o) => o.weapon)
|
||||||
|
|
||||||
|
if (mainWeapon)
|
||||||
|
newSearchGrid.unshift(mainWeapon.weapon)
|
||||||
|
|
||||||
|
setSearchGrid(newSearchGrid)
|
||||||
|
}, [weapons, mainWeapon])
|
||||||
|
|
||||||
|
// Methods: Adding an object from search
|
||||||
function openSearchModal(position: number) {
|
function openSearchModal(position: number) {
|
||||||
setSearchPosition(position)
|
setItemPositionForSearch(position)
|
||||||
openModal()
|
openModal()
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
function receiveWeaponFromSearch(object: Character | Weapon | Summon, position: number) {
|
||||||
<div id="weapon_grids">
|
const weapon = object as Weapon
|
||||||
<div id="WeaponGrid">
|
|
||||||
|
if (!partyId) {
|
||||||
|
props.createParty()
|
||||||
|
.then(response => {
|
||||||
|
const party = response.data.party
|
||||||
|
setPartyId(party.id)
|
||||||
|
|
||||||
|
if (props.pushHistory) props.pushHistory(`/p/${party.shortcode}`)
|
||||||
|
saveWeapon(party.id, weapon, position)
|
||||||
|
.then(response => storeGridWeapon(response.data.grid_weapon))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
saveWeapon(partyId, weapon, position)
|
||||||
|
.then(response => storeGridWeapon(response.data.grid_weapon))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveWeapon(partyId: string, weapon: Weapon, position: number) {
|
||||||
|
let uncapLevel = 3
|
||||||
|
if (weapon.uncap.ulb) uncapLevel = 5
|
||||||
|
else if (weapon.uncap.flb) uncapLevel = 4
|
||||||
|
|
||||||
|
return await api.endpoints.weapons.create({
|
||||||
|
'weapon': {
|
||||||
|
'party_id': partyId,
|
||||||
|
'weapon_id': weapon.id,
|
||||||
|
'position': position,
|
||||||
|
'mainhand': (position == -1),
|
||||||
|
'uncap_level': uncapLevel
|
||||||
|
}
|
||||||
|
}, headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
function storeGridWeapon(gridWeapon: GridWeapon) {
|
||||||
|
if (gridWeapon.position == -1) {
|
||||||
|
setMainWeapon(gridWeapon)
|
||||||
|
} else {
|
||||||
|
// Store the grid unit at the correct position
|
||||||
|
let newWeapons = Object.assign({}, weapons)
|
||||||
|
newWeapons[gridWeapon.position] = gridWeapon
|
||||||
|
setWeapons(newWeapons)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods: Updating uncap level
|
||||||
|
// Note: Saves, but debouncing is not working properly
|
||||||
|
async function saveUncap(id: string, position: number, uncapLevel: number) {
|
||||||
|
storePreviousUncapValue(position)
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (uncapLevel != previousUncapValues[position])
|
||||||
|
await api.updateUncap('weapon', id, uncapLevel)
|
||||||
|
.then(response => { storeGridWeapon(response.data.grid_weapon) })
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
|
||||||
|
// Revert optimistic UI
|
||||||
|
updateUncapLevel(position, previousUncapValues[position])
|
||||||
|
|
||||||
|
// Remove optimistic key
|
||||||
|
let newPreviousValues = {...previousUncapValues}
|
||||||
|
delete newPreviousValues[position]
|
||||||
|
setPreviousUncapValues(newPreviousValues)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initiateUncapUpdate(id: string, position: number, uncapLevel: number) {
|
||||||
|
memoizeAction(id, position, uncapLevel)
|
||||||
|
|
||||||
|
// Optimistically update UI
|
||||||
|
updateUncapLevel(position, uncapLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
const memoizeAction = useCallback(
|
||||||
|
(id: string, position: number, uncapLevel: number) => {
|
||||||
|
debouncedAction(id, position, uncapLevel)
|
||||||
|
}, [props, previousUncapValues]
|
||||||
|
)
|
||||||
|
|
||||||
|
const debouncedAction = useMemo(() =>
|
||||||
|
debounce((id, position, number) => {
|
||||||
|
saveUncap(id, position, number)
|
||||||
|
}, 500), [props, saveUncap]
|
||||||
|
)
|
||||||
|
|
||||||
|
const updateUncapLevel = (position: number, uncapLevel: number) => {
|
||||||
|
if (mainWeapon && position == -1) {
|
||||||
|
mainWeapon.uncap_level = uncapLevel
|
||||||
|
setMainWeapon(mainWeapon)
|
||||||
|
} else {
|
||||||
|
let newWeapons = Object.assign({}, weapons)
|
||||||
|
newWeapons[position].uncap_level = uncapLevel
|
||||||
|
setWeapons(newWeapons)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function storePreviousUncapValue(position: number) {
|
||||||
|
// Save the current value in case of an unexpected result
|
||||||
|
let newPreviousValues = {...previousUncapValues}
|
||||||
|
newPreviousValues[position] = (mainWeapon && position == -1) ? mainWeapon.uncap_level : weapons[position].uncap_level
|
||||||
|
setPreviousUncapValues(newPreviousValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render: JSX components
|
||||||
|
const mainhandElement = (
|
||||||
<WeaponUnit
|
<WeaponUnit
|
||||||
onClick={() => { openSearchModal(-1) }}
|
gridWeapon={mainWeapon}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
key="grid_mainhand"
|
key="grid_mainhand"
|
||||||
position={-1}
|
position={-1}
|
||||||
unitType={0}
|
unitType={0}
|
||||||
weapon={props.mainhand}
|
onClick={() => { openSearchModal(-1) }}
|
||||||
|
updateUncap={initiateUncapUpdate}
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
<ul id="grid_weapons">
|
const weaponGridElement = (
|
||||||
{
|
|
||||||
Array.from(Array(numWeapons)).map((x, i) => {
|
Array.from(Array(numWeapons)).map((x, i) => {
|
||||||
return (
|
return (
|
||||||
<li key={`grid_unit_${i}`} >
|
<li key={`grid_unit_${i}`} >
|
||||||
<WeaponUnit
|
<WeaponUnit
|
||||||
onClick={() => { openSearchModal(i) }}
|
gridWeapon={weapons[i]}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
position={i}
|
position={i}
|
||||||
unitType={1}
|
unitType={1}
|
||||||
weapon={props.grid[i]}
|
onClick={() => { openSearchModal(i) }}
|
||||||
|
updateUncap={initiateUncapUpdate}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
)
|
||||||
</ul>
|
|
||||||
|
const extraGridElement = (
|
||||||
|
<ExtraWeapons
|
||||||
|
grid={weapons}
|
||||||
|
editable={props.editable}
|
||||||
|
offset={numWeapons}
|
||||||
|
onClick={openSearchModal}
|
||||||
|
updateUncap={initiateUncapUpdate}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div id="weapon_grids">
|
||||||
|
<div id="WeaponGrid">
|
||||||
|
{ mainhandElement }
|
||||||
|
<ul id="grid_weapons">{ weaponGridElement }</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ (() => {
|
{ (() => { return (props.extra) ? extraGridElement : '' })() }
|
||||||
if(props.extra) {
|
|
||||||
return extraGrid
|
|
||||||
}
|
|
||||||
})() }
|
|
||||||
|
|
||||||
{open ? (
|
{open ? (
|
||||||
<SearchModal
|
<SearchModal
|
||||||
grid={props.grid}
|
grid={searchGrid}
|
||||||
close={closeModal}
|
close={closeModal}
|
||||||
send={sendData}
|
send={receiveWeaponFromSearch}
|
||||||
fromPosition={searchPosition}
|
fromPosition={itemPositionForSearch}
|
||||||
object="weapons"
|
object="weapons"
|
||||||
placeholderText="Search for a weapon..."
|
placeholderText="Search for a weapon..."
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
margin-bottom: 2px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: all 0.18s ease-in-out;
|
transition: all 0.18s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +20,11 @@
|
||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
box-shadow: rgba(0, 0, 0, 0.14) 0px 0px 14px;
|
box-shadow: rgba(0, 0, 0, 0.14) 0px 0px 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transform: scale(1.1, 1.1);
|
transform: $scale-wide;
|
||||||
|
}
|
||||||
|
|
||||||
|
.WeaponUnit.mainhand.editable .WeaponImage:hover {
|
||||||
|
transform: $scale-tall;
|
||||||
}
|
}
|
||||||
|
|
||||||
.WeaponUnit.filled h3 {
|
.WeaponUnit.filled h3 {
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,18 @@
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
|
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
|
|
||||||
import UncapIndicator from '~components/UncapIndicator'
|
import UncapIndicator from '~components/UncapIndicator'
|
||||||
|
|
||||||
import PlusIcon from '~public/icons/plus.svg'
|
import PlusIcon from '~public/icons/plus.svg'
|
||||||
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onClick: () => void
|
gridWeapon: GridWeapon | undefined
|
||||||
weapon: Weapon | undefined
|
unitType: 0 | 1
|
||||||
position: number
|
position: number
|
||||||
editable: boolean
|
editable: boolean
|
||||||
unitType: 0 | 1
|
onClick: () => void
|
||||||
|
updateUncap: (id: string, position: number, uncap: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const WeaponUnit = (props: Props) => {
|
const WeaponUnit = (props: Props) => {
|
||||||
|
|
@ -24,10 +23,11 @@ const WeaponUnit = (props: Props) => {
|
||||||
'mainhand': props.unitType == 0,
|
'mainhand': props.unitType == 0,
|
||||||
'grid': props.unitType == 1,
|
'grid': props.unitType == 1,
|
||||||
'editable': props.editable,
|
'editable': props.editable,
|
||||||
'filled': (props.weapon !== undefined)
|
'filled': (props.gridWeapon !== undefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
const weapon = props.weapon
|
const gridWeapon = props.gridWeapon
|
||||||
|
const weapon = gridWeapon?.weapon
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
generateImageUrl()
|
generateImageUrl()
|
||||||
|
|
@ -35,8 +35,8 @@ const WeaponUnit = (props: Props) => {
|
||||||
|
|
||||||
function generateImageUrl() {
|
function generateImageUrl() {
|
||||||
let imgSrc = ""
|
let imgSrc = ""
|
||||||
if (props.weapon) {
|
if (props.gridWeapon) {
|
||||||
const weapon = props.weapon!
|
const weapon = props.gridWeapon.weapon!
|
||||||
|
|
||||||
if (props.unitType == 0)
|
if (props.unitType == 0)
|
||||||
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${weapon.granblue_id}.jpg`
|
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${weapon.granblue_id}.jpg`
|
||||||
|
|
@ -47,6 +47,11 @@ const WeaponUnit = (props: Props) => {
|
||||||
setImageUrl(imgSrc)
|
setImageUrl(imgSrc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function passUncapData(uncap: number) {
|
||||||
|
if (props.gridWeapon)
|
||||||
|
props.updateUncap(props.gridWeapon.id, props.position, uncap)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className={classes}>
|
<div className={classes}>
|
||||||
|
|
@ -54,13 +59,17 @@ const WeaponUnit = (props: Props) => {
|
||||||
<img alt={weapon?.name.en} className="grid_image" src={imageUrl} />
|
<img alt={weapon?.name.en} className="grid_image" src={imageUrl} />
|
||||||
{ (props.editable) ? <span className='icon'><PlusIcon /></span> : '' }
|
{ (props.editable) ? <span className='icon'><PlusIcon /></span> : '' }
|
||||||
</div>
|
</div>
|
||||||
|
<h3 className="WeaponName">{weapon?.name.en}</h3>
|
||||||
|
{ (gridWeapon) ?
|
||||||
<UncapIndicator
|
<UncapIndicator
|
||||||
type="weapon"
|
type="weapon"
|
||||||
ulb={weapon?.uncap.ulb || false}
|
ulb={gridWeapon.weapon.uncap.ulb || false}
|
||||||
flb={weapon?.uncap.flb || false}
|
flb={gridWeapon.weapon.uncap.flb || false}
|
||||||
uncapLevel={3}
|
uncapLevel={gridWeapon.uncap_level}
|
||||||
/>
|
updateUncap={passUncapData}
|
||||||
<h3 className="WeaponName">{weapon?.name.en}</h3>
|
special={false}
|
||||||
|
/> : ''
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
50
package-lock.json
generated
|
|
@ -12,8 +12,10 @@
|
||||||
"@radix-ui/react-label": "^0.1.4",
|
"@radix-ui/react-label": "^0.1.4",
|
||||||
"@radix-ui/react-switch": "^0.1.4",
|
"@radix-ui/react-switch": "^0.1.4",
|
||||||
"@svgr/webpack": "^6.2.0",
|
"@svgr/webpack": "^6.2.0",
|
||||||
|
"@types/axios": "^0.14.0",
|
||||||
"axios": "^0.25.0",
|
"axios": "^0.25.0",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
"meyer-reset-scss": "^2.0.4",
|
"meyer-reset-scss": "^2.0.4",
|
||||||
"next": "12.0.8",
|
"next": "12.0.8",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
|
|
@ -23,6 +25,7 @@
|
||||||
"sass": "^1.49.0"
|
"sass": "^1.49.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/lodash.debounce": "^4.0.6",
|
||||||
"@types/node": "17.0.11",
|
"@types/node": "17.0.11",
|
||||||
"@types/react": "17.0.38",
|
"@types/react": "17.0.38",
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^17.0.11",
|
||||||
|
|
@ -2980,6 +2983,15 @@
|
||||||
"node": ">=10.13.0"
|
"node": ">=10.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/axios": {
|
||||||
|
"version": "0.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.14.0.tgz",
|
||||||
|
"integrity": "sha1-7CMA++fX3d1+udOr+HmZlkyvzkY=",
|
||||||
|
"deprecated": "This is a stub types definition for axios (https://github.com/mzabriskie/axios). axios provides its own type definitions, so you don't need @types/axios installed!",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/cookie": {
|
"node_modules/@types/cookie": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz",
|
||||||
|
|
@ -3000,6 +3012,21 @@
|
||||||
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
|
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/lodash": {
|
||||||
|
"version": "4.14.178",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz",
|
||||||
|
"integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/@types/lodash.debounce": {
|
||||||
|
"version": "4.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.6.tgz",
|
||||||
|
"integrity": "sha512-4WTmnnhCfDvvuLMaF3KV4Qfki93KebocUF45msxhYyjMttZDQYzHkO639ohhk8+oco2cluAFL3t5+Jn4mleylQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/lodash": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "17.0.11",
|
"version": "17.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.11.tgz",
|
||||||
|
|
@ -8737,6 +8764,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
||||||
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="
|
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="
|
||||||
},
|
},
|
||||||
|
"@types/axios": {
|
||||||
|
"version": "0.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.14.0.tgz",
|
||||||
|
"integrity": "sha1-7CMA++fX3d1+udOr+HmZlkyvzkY=",
|
||||||
|
"requires": {
|
||||||
|
"axios": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/cookie": {
|
"@types/cookie": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz",
|
||||||
|
|
@ -8757,6 +8792,21 @@
|
||||||
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
|
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/lodash": {
|
||||||
|
"version": "4.14.178",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz",
|
||||||
|
"integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/lodash.debounce": {
|
||||||
|
"version": "4.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.6.tgz",
|
||||||
|
"integrity": "sha512-4WTmnnhCfDvvuLMaF3KV4Qfki93KebocUF45msxhYyjMttZDQYzHkO639ohhk8+oco2cluAFL3t5+Jn4mleylQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/lodash": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "17.0.11",
|
"version": "17.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.11.tgz",
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,10 @@
|
||||||
"@radix-ui/react-label": "^0.1.4",
|
"@radix-ui/react-label": "^0.1.4",
|
||||||
"@radix-ui/react-switch": "^0.1.4",
|
"@radix-ui/react-switch": "^0.1.4",
|
||||||
"@svgr/webpack": "^6.2.0",
|
"@svgr/webpack": "^6.2.0",
|
||||||
|
"@types/axios": "^0.14.0",
|
||||||
"axios": "^0.25.0",
|
"axios": "^0.25.0",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
"meyer-reset-scss": "^2.0.4",
|
"meyer-reset-scss": "^2.0.4",
|
||||||
"next": "12.0.8",
|
"next": "12.0.8",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
|
|
@ -28,6 +30,7 @@
|
||||||
"sass": "^1.49.0"
|
"sass": "^1.49.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/lodash.debounce": "^4.0.6",
|
||||||
"@types/node": "17.0.11",
|
"@types/node": "17.0.11",
|
||||||
"@types/react": "17.0.38",
|
"@types/react": "17.0.38",
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^17.0.11",
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,13 @@ const PartyRoute: React.FC = () => {
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
const [editable, setEditable] = useState(false)
|
const [editable, setEditable] = useState(false)
|
||||||
|
|
||||||
const [characters, setCharacters] = useState<GridArray<Character>>({})
|
const [characters, setCharacters] = useState<GridArray<GridCharacter>>({})
|
||||||
const [weapons, setWeapons] = useState<GridArray<Weapon>>({})
|
const [weapons, setWeapons] = useState<GridArray<GridWeapon>>({})
|
||||||
const [summons, setSummons] = useState<GridArray<Summon>>({})
|
const [summons, setSummons] = useState<GridArray<GridSummon>>({})
|
||||||
|
|
||||||
const [mainWeapon, setMainWeapon] = useState<Weapon>()
|
const [mainWeapon, setMainWeapon] = useState<GridWeapon>()
|
||||||
const [mainSummon, setMainSummon] = useState<Summon>()
|
const [mainSummon, setMainSummon] = useState<GridSummon>()
|
||||||
const [friendSummon, setFriendSummon] = useState<Summon>()
|
const [friendSummon, setFriendSummon] = useState<GridSummon>()
|
||||||
|
|
||||||
const [partyId, setPartyId] = useState('')
|
const [partyId, setPartyId] = useState('')
|
||||||
const [extra, setExtra] = useState<boolean>(false)
|
const [extra, setExtra] = useState<boolean>(false)
|
||||||
|
|
@ -73,39 +73,39 @@ const PartyRoute: React.FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateCharacters(list: [GridCharacter]) {
|
function populateCharacters(list: [GridCharacter]) {
|
||||||
let characters: GridArray<Character> = {}
|
let characters: GridArray<GridCharacter> = {}
|
||||||
|
|
||||||
list.forEach((object: GridCharacter) => {
|
list.forEach((object: GridCharacter) => {
|
||||||
if (object.position != null)
|
if (object.position != null)
|
||||||
characters[object.position] = object.character
|
characters[object.position] = object
|
||||||
})
|
})
|
||||||
|
|
||||||
return characters
|
return characters
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateWeapons(list: [GridWeapon]) {
|
function populateWeapons(list: [GridWeapon]) {
|
||||||
let weapons: GridArray<Weapon> = {}
|
let weapons: GridArray<GridWeapon> = {}
|
||||||
|
|
||||||
list.forEach((object: GridWeapon) => {
|
list.forEach((object: GridWeapon) => {
|
||||||
if (object.mainhand)
|
if (object.mainhand)
|
||||||
setMainWeapon(object.weapon)
|
setMainWeapon(object)
|
||||||
else if (!object.mainhand && object.position != null)
|
else if (!object.mainhand && object.position != null)
|
||||||
weapons[object.position] = object.weapon
|
weapons[object.position] = object
|
||||||
})
|
})
|
||||||
|
|
||||||
return weapons
|
return weapons
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateSummons(list: [GridSummon]) {
|
function populateSummons(list: [GridSummon]) {
|
||||||
let summons: GridArray<Summon> = {}
|
let summons: GridArray<GridSummon> = {}
|
||||||
|
|
||||||
list.forEach((object: GridSummon) => {
|
list.forEach((object: GridSummon) => {
|
||||||
if (object.main)
|
if (object.main)
|
||||||
setMainSummon(object.summon)
|
setMainSummon(object)
|
||||||
else if (object.friend)
|
else if (object.friend)
|
||||||
setFriendSummon(object.summon)
|
setFriendSummon(object)
|
||||||
else if (!object.main && !object.friend && object.position != null)
|
else if (!object.main && !object.friend && object.position != null)
|
||||||
summons[object.position] = object.summon
|
summons[object.position] = object
|
||||||
})
|
})
|
||||||
|
|
||||||
return summons
|
return summons
|
||||||
|
|
@ -129,7 +129,6 @@ const PartyRoute: React.FC = () => {
|
||||||
weapons={weapons}
|
weapons={weapons}
|
||||||
summons={summons}
|
summons={summons}
|
||||||
editable={editable}
|
editable={editable}
|
||||||
exists={found}
|
|
||||||
extra={extra}
|
extra={extra}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
44
public/icons/uncap/blue-hover.svg
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_d_855_1312)">
|
||||||
|
<path d="M8.52447 1.46353C8.67415 1.00287 9.32585 1.00287 9.47553 1.46353L10.9084 5.87336C10.9753 6.07937 11.1673 6.21885 11.3839 6.21885H16.0207C16.505 6.21885 16.7064 6.83865 16.3146 7.12336L12.5633 9.84878C12.3881 9.9761 12.3148 10.2018 12.3817 10.4078L13.8145 14.8176C13.9642 15.2783 13.437 15.6613 13.0451 15.3766L9.29389 12.6512C9.11865 12.5239 8.88135 12.5239 8.70611 12.6512L4.95488 15.3766C4.56303 15.6613 4.03578 15.2783 4.18546 14.8176L5.6183 10.4078C5.68524 10.2018 5.61191 9.9761 5.43667 9.84878L1.68544 7.12336C1.29358 6.83866 1.49497 6.21885 1.97933 6.21885H6.6161C6.83272 6.21885 7.02469 6.07937 7.09163 5.87336L8.52447 1.46353Z" fill="url(#paint0_radial_855_1312)"/>
|
||||||
|
<path d="M8.61958 1.49443C8.73932 1.1259 9.26068 1.1259 9.38042 1.49443L10.8133 5.90426C10.8936 6.15147 11.124 6.31885 11.3839 6.31885H16.0207C16.4082 6.31885 16.5693 6.81469 16.2558 7.04245L12.5046 9.76788C12.2943 9.92066 12.2063 10.1915 12.2866 10.4387L13.7194 14.8485C13.8392 15.2171 13.4174 15.5235 13.1039 15.2957L9.35267 12.5703C9.14238 12.4175 8.85762 12.4175 8.64733 12.5703L4.8961 15.2957C4.58262 15.5235 4.16083 15.2171 4.28057 14.8485L5.71341 10.4387C5.79373 10.1915 5.70574 9.92066 5.49544 9.76788L1.74422 7.04245C1.43073 6.81469 1.59184 6.31885 1.97933 6.31885H6.6161C6.87604 6.31885 7.10641 6.15147 7.18674 5.90426L8.61958 1.49443Z" stroke="white" stroke-opacity="0.34" stroke-width="0.2"/>
|
||||||
|
</g>
|
||||||
|
<path opacity="0.3" fill-rule="evenodd" clip-rule="evenodd" d="M9.47555 1.46353C9.40071 1.2332 9.20035 1.11804 9 1.11804V9L6.93514 6.10386C6.84752 6.17645 6.73556 6.21885 6.61612 6.21885H1.97935C1.73204 6.21885 1.5585 6.38044 1.50004 6.5765L9 9L5.61832 10.0988C5.65019 10.1969 5.65179 10.3048 5.61832 10.4078L4.18548 14.8176C4.11064 15.048 4.20503 15.2589 4.36711 15.3767L9 9V12.5557C9.10314 12.5557 9.20628 12.5876 9.29391 12.6512L13.0451 15.3767C13.2411 15.519 13.4708 15.4944 13.6329 15.3767L9 9L12.3817 10.0988C12.4136 10.0007 12.4757 9.91245 12.5634 9.84879L16.3146 7.12336C16.5064 6.98403 16.556 6.76443 16.5 6.5765L9 9L11.0649 6.10386C10.9936 6.0448 10.9384 5.96578 10.9084 5.87336L9.47555 1.46353Z" fill="url(#paint1_linear_855_1312)"/>
|
||||||
|
<g filter="url(#filter1_d_855_1312)">
|
||||||
|
<path d="M10.7182 5.93517L9.28535 1.52534C9.24047 1.38718 9.12031 1.31808 9.00014 1.31804V1.11804C9.20045 1.11808 9.40074 1.23325 9.47557 1.46353L10.9084 5.87336C10.9383 5.96521 10.9929 6.04383 11.0636 6.10277L10.9484 6.26685C10.8432 6.18328 10.7618 6.0693 10.7182 5.93517Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M6.61614 6.41885H1.97937C1.82926 6.41885 1.72445 6.51807 1.69059 6.63755L1.50171 6.57107C1.56174 6.37747 1.73435 6.21885 1.97937 6.21885H6.61614C6.73521 6.21885 6.84683 6.17671 6.93434 6.10454L7.05278 6.26598C6.93164 6.36264 6.77886 6.41885 6.61614 6.41885Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M5.80855 10.4696L4.37571 14.8794C4.33081 15.0176 4.38744 15.1442 4.48469 15.2148L4.36714 15.3767C4.20505 15.2589 4.11066 15.048 4.1855 14.8176L5.61834 10.4078C5.65181 10.3048 5.65021 10.1969 5.61834 10.0988L5.80855 10.037C5.85317 10.1743 5.85541 10.3254 5.80855 10.4696Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M9.41149 12.4894L13.1627 15.2148C13.2803 15.3003 13.4181 15.2855 13.5154 15.2148L13.6329 15.3767C13.4709 15.4944 13.2411 15.519 13.0452 15.3767L9.29393 12.6512C9.2063 12.5876 9.10315 12.5557 9 12.5557V12.3557C9.1444 12.3557 9.28881 12.4003 9.41149 12.4894Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M12.4458 9.68698L16.197 6.96156C16.3099 6.87954 16.3408 6.75116 16.3101 6.63985L16.4998 6.57588C16.5562 6.76394 16.5066 6.98387 16.3146 7.12336L12.5634 9.84879C12.4758 9.91245 12.4136 10.0007 12.3817 10.0988L12.1915 10.037C12.2361 9.89966 12.3231 9.77611 12.4458 9.68698Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_855_1312" x="0.478374" y="0.118034" width="17.0433" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_855_1312"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_855_1312" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_d_855_1312" x="0.501709" y="0.118042" width="17.02" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_855_1312"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_855_1312" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient id="paint0_radial_855_1312" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9 7.5) rotate(90) scale(7.5)">
|
||||||
|
<stop stop-color="#A4D8FD"/>
|
||||||
|
<stop offset="1" stop-color="#4FA4F2"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint1_linear_855_1312" x1="5" y1="-1.5" x2="10" y2="14" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#A4D9FF"/>
|
||||||
|
<stop offset="1" stop-color="#4194F7"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.7 KiB |
44
public/icons/uncap/blue.svg
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_d_553_28)">
|
||||||
|
<path d="M8.52447 1.46353C8.67415 1.00287 9.32585 1.00287 9.47553 1.46353L10.9084 5.87336C10.9753 6.07937 11.1673 6.21885 11.3839 6.21885H16.0207C16.505 6.21885 16.7064 6.83865 16.3146 7.12336L12.5633 9.84878C12.3881 9.9761 12.3148 10.2018 12.3817 10.4078L13.8145 14.8176C13.9642 15.2783 13.437 15.6613 13.0451 15.3766L9.29389 12.6512C9.11865 12.5239 8.88135 12.5239 8.70611 12.6512L4.95488 15.3766C4.56303 15.6613 4.03578 15.2783 4.18546 14.8176L5.6183 10.4078C5.68524 10.2018 5.61191 9.9761 5.43667 9.84878L1.68544 7.12336C1.29358 6.83866 1.49497 6.21885 1.97933 6.21885H6.6161C6.83272 6.21885 7.02469 6.07937 7.09163 5.87336L8.52447 1.46353Z" fill="url(#paint0_radial_553_28)"/>
|
||||||
|
<path d="M8.61958 1.49443C8.73932 1.1259 9.26068 1.1259 9.38042 1.49443L10.8133 5.90426C10.8936 6.15147 11.124 6.31885 11.3839 6.31885H16.0207C16.4082 6.31885 16.5693 6.81469 16.2558 7.04245L12.5046 9.76788C12.2943 9.92066 12.2063 10.1915 12.2866 10.4387L13.7194 14.8485C13.8392 15.2171 13.4174 15.5235 13.1039 15.2957L9.35267 12.5703C9.14238 12.4175 8.85762 12.4175 8.64733 12.5703L4.8961 15.2957C4.58262 15.5235 4.16083 15.2171 4.28057 14.8485L5.71341 10.4387C5.79373 10.1915 5.70574 9.92066 5.49544 9.76788L1.74422 7.04245C1.43073 6.81469 1.59184 6.31885 1.97933 6.31885H6.6161C6.87604 6.31885 7.10641 6.15147 7.18674 5.90426L8.61958 1.49443Z" stroke="white" stroke-opacity="0.34" stroke-width="0.2"/>
|
||||||
|
</g>
|
||||||
|
<path opacity="0.3" fill-rule="evenodd" clip-rule="evenodd" d="M9.47555 1.46353C9.40071 1.2332 9.20035 1.11804 9 1.11804V9L6.93514 6.10386C6.84752 6.17645 6.73556 6.21885 6.61612 6.21885H1.97935C1.73204 6.21885 1.5585 6.38044 1.50004 6.5765L9 9L5.61832 10.0988C5.65019 10.1969 5.65179 10.3048 5.61832 10.4078L4.18548 14.8176C4.11064 15.048 4.20503 15.2589 4.36711 15.3767L9 9V12.5557C9.10314 12.5557 9.20628 12.5876 9.29391 12.6512L13.0451 15.3767C13.2411 15.519 13.4708 15.4944 13.6329 15.3767L9 9L12.3817 10.0988C12.4136 10.0007 12.4757 9.91245 12.5634 9.84879L16.3146 7.12336C16.5064 6.98403 16.556 6.76443 16.5 6.5765L9 9L11.0649 6.10386C10.9936 6.0448 10.9384 5.96578 10.9084 5.87336L9.47555 1.46353Z" fill="url(#paint1_linear_553_28)"/>
|
||||||
|
<g filter="url(#filter1_d_553_28)">
|
||||||
|
<path d="M10.7182 5.93517L9.28535 1.52534C9.24047 1.38718 9.12031 1.31808 9.00014 1.31804V1.11804C9.20045 1.11808 9.40074 1.23325 9.47557 1.46353L10.9084 5.87336C10.9383 5.96521 10.9929 6.04383 11.0636 6.10277L10.9484 6.26685C10.8432 6.18328 10.7618 6.0693 10.7182 5.93517Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M6.61614 6.41885H1.97937C1.82926 6.41885 1.72445 6.51807 1.69059 6.63755L1.50171 6.57107C1.56174 6.37747 1.73435 6.21885 1.97937 6.21885H6.61614C6.73521 6.21885 6.84683 6.17671 6.93434 6.10454L7.05278 6.26598C6.93164 6.36264 6.77886 6.41885 6.61614 6.41885Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M5.80855 10.4696L4.37571 14.8794C4.33081 15.0176 4.38744 15.1442 4.48469 15.2148L4.36714 15.3767C4.20505 15.2589 4.11066 15.048 4.1855 14.8176L5.61834 10.4078C5.65181 10.3048 5.65021 10.1969 5.61834 10.0988L5.80855 10.037C5.85317 10.1743 5.85541 10.3254 5.80855 10.4696Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M9.41149 12.4894L13.1627 15.2148C13.2803 15.3003 13.4181 15.2855 13.5154 15.2148L13.6329 15.3767C13.4709 15.4944 13.2411 15.519 13.0452 15.3767L9.29393 12.6512C9.2063 12.5876 9.10315 12.5557 9 12.5557V12.3557C9.1444 12.3557 9.28881 12.4003 9.41149 12.4894Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M12.4458 9.68698L16.197 6.96156C16.3099 6.87954 16.3408 6.75116 16.3101 6.63985L16.4998 6.57588C16.5562 6.76394 16.5066 6.98387 16.3146 7.12336L12.5634 9.84879C12.4758 9.91245 12.4136 10.0007 12.3817 10.0988L12.1915 10.037C12.2361 9.89966 12.3231 9.77611 12.4458 9.68698Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_553_28" x="0.478374" y="0.118034" width="17.0433" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_553_28"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_553_28" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_d_553_28" x="0.501709" y="0.118042" width="17.02" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_553_28"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_553_28" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient id="paint0_radial_553_28" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9 7.5) rotate(90) scale(7.5)">
|
||||||
|
<stop stop-color="#B2DEFE"/>
|
||||||
|
<stop offset="1" stop-color="#72BBFF"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint1_linear_553_28" x1="5" y1="-1.5" x2="10" y2="14" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#BCE1FC"/>
|
||||||
|
<stop offset="1" stop-color="#519CF4"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.7 KiB |
25
public/icons/uncap/empty-hover.svg
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_dd_855_1310)">
|
||||||
|
<path d="M8.52447 1.46353C8.67415 1.00287 9.32585 1.00287 9.47553 1.46353L10.9084 5.87336C10.9753 6.07937 11.1673 6.21885 11.3839 6.21885H16.0207C16.505 6.21885 16.7064 6.83866 16.3146 7.12336L12.5633 9.84878C12.3881 9.9761 12.3148 10.2018 12.3817 10.4078L13.8145 14.8176C13.9642 15.2783 13.437 15.6613 13.0451 15.3766L9.29389 12.6512C9.11865 12.5239 8.88135 12.5239 8.70611 12.6512L4.95488 15.3766C4.56303 15.6613 4.03578 15.2783 4.18546 14.8176L5.6183 10.4078C5.68524 10.2018 5.61191 9.9761 5.43667 9.84878L1.68544 7.12336C1.29358 6.83866 1.49497 6.21885 1.97933 6.21885H6.6161C6.83272 6.21885 7.02469 6.07937 7.09163 5.87336L8.52447 1.46353Z" fill="url(#paint0_radial_855_1310)"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_dd_855_1310" x="1.47838" y="0.618034" width="15.0432" height="15.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="-0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_855_1310"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||||
|
<feBlend mode="normal" in2="effect1_dropShadow_855_1310" result="effect2_dropShadow_855_1310"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_855_1310" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient id="paint0_radial_855_1310" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9 10) rotate(90) scale(14.5 13.75)">
|
||||||
|
<stop stop-color="#4B4B4B"/>
|
||||||
|
<stop offset="1" stop-color="#FFFEFE"/>
|
||||||
|
</radialGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.1 KiB |
25
public/icons/uncap/empty.svg
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_dd_562_3660)">
|
||||||
|
<path d="M8.52447 1.46353C8.67415 1.00287 9.32585 1.00287 9.47553 1.46353L10.9084 5.87336C10.9753 6.07937 11.1673 6.21885 11.3839 6.21885H16.0207C16.505 6.21885 16.7064 6.83865 16.3146 7.12336L12.5633 9.84878C12.3881 9.9761 12.3148 10.2018 12.3817 10.4078L13.8145 14.8176C13.9642 15.2783 13.437 15.6613 13.0451 15.3766L9.29389 12.6512C9.11865 12.5239 8.88135 12.5239 8.70611 12.6512L4.95488 15.3766C4.56303 15.6613 4.03578 15.2783 4.18546 14.8176L5.6183 10.4078C5.68524 10.2018 5.61191 9.9761 5.43667 9.84878L1.68544 7.12336C1.29358 6.83866 1.49497 6.21885 1.97933 6.21885H6.6161C6.83272 6.21885 7.02469 6.07937 7.09163 5.87336L8.52447 1.46353Z" fill="url(#paint0_radial_562_3660)"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_dd_562_3660" x="1.47838" y="0.618034" width="15.0432" height="15.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="-0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.24 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_562_3660"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||||
|
<feBlend mode="normal" in2="effect1_dropShadow_562_3660" result="effect2_dropShadow_562_3660"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_562_3660" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient id="paint0_radial_562_3660" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9 10) rotate(90) scale(14.5)">
|
||||||
|
<stop stop-color="#333333"/>
|
||||||
|
<stop offset="1" stop-color="#D0D0D0"/>
|
||||||
|
</radialGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.1 KiB |
44
public/icons/uncap/purple-hover.svg
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_d_855_1316)">
|
||||||
|
<path d="M8.52447 1.46353C8.67415 1.00287 9.32585 1.00287 9.47553 1.46353L10.9084 5.87336C10.9753 6.07937 11.1673 6.21885 11.3839 6.21885H16.0207C16.505 6.21885 16.7064 6.83865 16.3146 7.12336L12.5633 9.84878C12.3881 9.9761 12.3148 10.2018 12.3817 10.4078L13.8145 14.8176C13.9642 15.2783 13.437 15.6613 13.0451 15.3766L9.29389 12.6512C9.11865 12.5239 8.88135 12.5239 8.70611 12.6512L4.95488 15.3766C4.56303 15.6613 4.03578 15.2783 4.18546 14.8176L5.6183 10.4078C5.68524 10.2018 5.61191 9.9761 5.43667 9.84878L1.68544 7.12336C1.29358 6.83866 1.49497 6.21885 1.97933 6.21885H6.6161C6.83272 6.21885 7.02469 6.07937 7.09163 5.87336L8.52447 1.46353Z" fill="url(#paint0_radial_855_1316)"/>
|
||||||
|
<path d="M8.61958 1.49443C8.73932 1.1259 9.26068 1.1259 9.38042 1.49443L10.8133 5.90426C10.8936 6.15147 11.124 6.31885 11.3839 6.31885H16.0207C16.4082 6.31885 16.5693 6.81469 16.2558 7.04245L12.5046 9.76788C12.2943 9.92066 12.2063 10.1915 12.2866 10.4387L13.7194 14.8485C13.8392 15.2171 13.4174 15.5235 13.1039 15.2957L9.35267 12.5703C9.14238 12.4175 8.85762 12.4175 8.64733 12.5703L4.8961 15.2957C4.58262 15.5235 4.16083 15.2171 4.28057 14.8485L5.71341 10.4387C5.79373 10.1915 5.70574 9.92066 5.49544 9.76788L1.74422 7.04245C1.43073 6.81469 1.59184 6.31885 1.97933 6.31885H6.6161C6.87604 6.31885 7.10641 6.15147 7.18674 5.90426L8.61958 1.49443Z" stroke="white" stroke-opacity="0.36" stroke-width="0.2"/>
|
||||||
|
</g>
|
||||||
|
<path opacity="0.3" fill-rule="evenodd" clip-rule="evenodd" d="M9.47555 1.46353C9.40071 1.2332 9.20035 1.11804 9 1.11804V9L6.93514 6.10386C6.84752 6.17645 6.73556 6.21885 6.61612 6.21885H1.97935C1.73204 6.21885 1.5585 6.38044 1.50004 6.5765L9 9L5.61832 10.0988C5.65019 10.1969 5.65179 10.3048 5.61832 10.4078L4.18548 14.8176C4.11064 15.048 4.20503 15.2589 4.36711 15.3767L9 9V12.5557C9.10314 12.5557 9.20628 12.5876 9.29391 12.6512L13.0451 15.3767C13.2411 15.519 13.4708 15.4944 13.6329 15.3767L9 9L12.3817 10.0988C12.4136 10.0007 12.4757 9.91245 12.5634 9.84879L16.3146 7.12336C16.5064 6.98403 16.556 6.76443 16.5 6.5765L9 9L11.0649 6.10386C10.9936 6.0448 10.9384 5.96578 10.9084 5.87336L9.47555 1.46353Z" fill="url(#paint1_linear_855_1316)"/>
|
||||||
|
<g filter="url(#filter1_d_855_1316)">
|
||||||
|
<path d="M10.7182 5.93516L9.28532 1.52533C9.24043 1.38717 9.12028 1.31807 9.0001 1.31803V1.11803C9.20041 1.11807 9.4007 1.23324 9.47553 1.46353L10.9084 5.87336C10.9382 5.9652 10.9929 6.04383 11.0636 6.10276L10.9483 6.26684C10.8432 6.18328 10.7617 6.06929 10.7182 5.93516Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M6.6161 6.41885H1.97933C1.82922 6.41885 1.72441 6.51807 1.69055 6.63755L1.50167 6.57106C1.5617 6.37746 1.73431 6.21885 1.97933 6.21885H6.6161C6.73517 6.21885 6.8468 6.1767 6.9343 6.10453L7.05275 6.26597C6.9316 6.36263 6.77882 6.41885 6.6161 6.41885Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M5.80851 10.4696L4.37567 14.8794C4.33077 15.0176 4.3874 15.1442 4.48465 15.2148L4.3671 15.3766C4.20501 15.2589 4.11062 15.048 4.18546 14.8176L5.6183 10.4078C5.65177 10.3048 5.65017 10.1969 5.6183 10.0988L5.80851 10.037C5.85313 10.1743 5.85537 10.3254 5.80851 10.4696Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M9.41145 12.4894L13.1627 15.2148C13.2802 15.3003 13.4181 15.2855 13.5153 15.2148L13.6329 15.3766C13.4708 15.4944 13.241 15.519 13.0451 15.3766L9.29389 12.6512C9.20626 12.5876 9.10311 12.5557 8.99996 12.5557V12.3557C9.14436 12.3557 9.28877 12.4003 9.41145 12.4894Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M12.4458 9.68698L16.197 6.96155C16.3099 6.87953 16.3407 6.75115 16.3101 6.63984L16.4998 6.57587C16.5561 6.76393 16.5066 6.98387 16.3146 7.12336L12.5633 9.84878C12.4757 9.91244 12.4136 10.0007 12.3817 10.0988L12.1915 10.037C12.2361 9.89965 12.3231 9.7761 12.4458 9.68698Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_855_1316" x="0.478378" y="0.118034" width="17.0432" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_855_1316"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_855_1316" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_d_855_1316" x="0.501671" y="0.118034" width="17.02" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_855_1316"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_855_1316" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient id="paint0_radial_855_1316" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9 7) rotate(90) scale(5 8.08499)">
|
||||||
|
<stop stop-color="#E7A3FF"/>
|
||||||
|
<stop offset="1" stop-color="#B369FE"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint1_linear_855_1316" x1="5" y1="-1.5" x2="10" y2="14" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#D5ABFF"/>
|
||||||
|
<stop offset="1" stop-color="#A547EE"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.7 KiB |
44
public/icons/uncap/purple.svg
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_d_553_29)">
|
||||||
|
<path d="M8.52447 1.46353C8.67415 1.00287 9.32585 1.00287 9.47553 1.46353L10.9084 5.87336C10.9753 6.07937 11.1673 6.21885 11.3839 6.21885H16.0207C16.505 6.21885 16.7064 6.83865 16.3146 7.12336L12.5633 9.84878C12.3881 9.9761 12.3148 10.2018 12.3817 10.4078L13.8145 14.8176C13.9642 15.2783 13.437 15.6613 13.0451 15.3766L9.29389 12.6512C9.11865 12.5239 8.88135 12.5239 8.70611 12.6512L4.95488 15.3766C4.56303 15.6613 4.03578 15.2783 4.18546 14.8176L5.6183 10.4078C5.68524 10.2018 5.61191 9.9761 5.43667 9.84878L1.68544 7.12336C1.29358 6.83866 1.49497 6.21885 1.97933 6.21885H6.6161C6.83272 6.21885 7.02469 6.07937 7.09163 5.87336L8.52447 1.46353Z" fill="url(#paint0_radial_553_29)"/>
|
||||||
|
<path d="M8.61958 1.49443C8.73932 1.1259 9.26068 1.1259 9.38042 1.49443L10.8133 5.90426C10.8936 6.15147 11.124 6.31885 11.3839 6.31885H16.0207C16.4082 6.31885 16.5693 6.81469 16.2558 7.04245L12.5046 9.76788C12.2943 9.92066 12.2063 10.1915 12.2866 10.4387L13.7194 14.8485C13.8392 15.2171 13.4174 15.5235 13.1039 15.2957L9.35267 12.5703C9.14238 12.4175 8.85762 12.4175 8.64733 12.5703L4.8961 15.2957C4.58262 15.5235 4.16083 15.2171 4.28057 14.8485L5.71341 10.4387C5.79373 10.1915 5.70574 9.92066 5.49544 9.76788L1.74422 7.04245C1.43073 6.81469 1.59184 6.31885 1.97933 6.31885H6.6161C6.87604 6.31885 7.10641 6.15147 7.18674 5.90426L8.61958 1.49443Z" stroke="white" stroke-opacity="0.36" stroke-width="0.2"/>
|
||||||
|
</g>
|
||||||
|
<path opacity="0.3" fill-rule="evenodd" clip-rule="evenodd" d="M9.47555 1.46353C9.40071 1.2332 9.20035 1.11804 9 1.11804V9L6.93514 6.10386C6.84752 6.17645 6.73556 6.21885 6.61612 6.21885H1.97935C1.73204 6.21885 1.5585 6.38044 1.50004 6.5765L9 9L5.61832 10.0988C5.65019 10.1969 5.65179 10.3048 5.61832 10.4078L4.18548 14.8176C4.11064 15.048 4.20503 15.2589 4.36711 15.3767L9 9V12.5557C9.10314 12.5557 9.20628 12.5876 9.29391 12.6512L13.0451 15.3767C13.2411 15.519 13.4708 15.4944 13.6329 15.3767L9 9L12.3817 10.0988C12.4136 10.0007 12.4757 9.91245 12.5634 9.84879L16.3146 7.12336C16.5064 6.98403 16.556 6.76443 16.5 6.5765L9 9L11.0649 6.10386C10.9936 6.0448 10.9384 5.96578 10.9084 5.87336L9.47555 1.46353Z" fill="url(#paint1_linear_553_29)"/>
|
||||||
|
<g filter="url(#filter1_d_553_29)">
|
||||||
|
<path d="M10.7182 5.93516L9.28532 1.52533C9.24043 1.38717 9.12028 1.31807 9.0001 1.31803V1.11803C9.20041 1.11807 9.4007 1.23324 9.47553 1.46353L10.9084 5.87336C10.9382 5.9652 10.9929 6.04383 11.0636 6.10276L10.9483 6.26684C10.8432 6.18328 10.7617 6.06929 10.7182 5.93516Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M6.6161 6.41885H1.97933C1.82922 6.41885 1.72441 6.51807 1.69055 6.63755L1.50167 6.57106C1.5617 6.37746 1.73431 6.21885 1.97933 6.21885H6.6161C6.73517 6.21885 6.8468 6.1767 6.9343 6.10453L7.05275 6.26597C6.9316 6.36263 6.77882 6.41885 6.6161 6.41885Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M5.80851 10.4696L4.37567 14.8794C4.33077 15.0176 4.3874 15.1442 4.48465 15.2148L4.3671 15.3766C4.20501 15.2589 4.11062 15.048 4.18546 14.8176L5.6183 10.4078C5.65177 10.3048 5.65017 10.1969 5.6183 10.0988L5.80851 10.037C5.85313 10.1743 5.85537 10.3254 5.80851 10.4696Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M9.41145 12.4894L13.1627 15.2148C13.2802 15.3003 13.4181 15.2855 13.5153 15.2148L13.6329 15.3766C13.4708 15.4944 13.241 15.519 13.0451 15.3766L9.29389 12.6512C9.20626 12.5876 9.10311 12.5557 8.99996 12.5557V12.3557C9.14436 12.3557 9.28877 12.4003 9.41145 12.4894Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M12.4458 9.68698L16.197 6.96155C16.3099 6.87953 16.3407 6.75115 16.3101 6.63984L16.4998 6.57587C16.5561 6.76393 16.5066 6.98387 16.3146 7.12336L12.5633 9.84878C12.4757 9.91244 12.4136 10.0007 12.3817 10.0988L12.1915 10.037C12.2361 9.89965 12.3231 9.7761 12.4458 9.68698Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_553_29" x="0.478378" y="0.118034" width="17.0432" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_553_29"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_553_29" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_d_553_29" x="0.501671" y="0.118034" width="17.02" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_553_29"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_553_29" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient id="paint0_radial_553_29" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9 7) rotate(90) scale(5 8.08499)">
|
||||||
|
<stop stop-color="#EAB2FE"/>
|
||||||
|
<stop offset="1" stop-color="#B872FF"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint1_linear_553_29" x1="5" y1="-1.5" x2="10" y2="14" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#DCBCFC"/>
|
||||||
|
<stop offset="1" stop-color="#AD51F4"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.7 KiB |
44
public/icons/uncap/red-hover.svg
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_d_855_1320)">
|
||||||
|
<path d="M8.52447 1.46353C8.67415 1.00287 9.32585 1.00287 9.47553 1.46353L10.9084 5.87336C10.9753 6.07937 11.1673 6.21885 11.3839 6.21885H16.0207C16.505 6.21885 16.7064 6.83865 16.3146 7.12336L12.5633 9.84878C12.3881 9.9761 12.3148 10.2018 12.3817 10.4078L13.8145 14.8176C13.9642 15.2783 13.437 15.6613 13.0451 15.3766L9.29389 12.6512C9.11865 12.5239 8.88135 12.5239 8.70611 12.6512L4.95488 15.3766C4.56303 15.6613 4.03578 15.2783 4.18546 14.8176L5.6183 10.4078C5.68524 10.2018 5.61191 9.9761 5.43667 9.84878L1.68544 7.12336C1.29358 6.83866 1.49497 6.21885 1.97933 6.21885H6.6161C6.83272 6.21885 7.02469 6.07937 7.09163 5.87336L8.52447 1.46353Z" fill="url(#paint0_radial_855_1320)"/>
|
||||||
|
<path d="M8.61958 1.49443C8.73932 1.1259 9.26068 1.1259 9.38042 1.49443L10.8133 5.90426C10.8936 6.15147 11.124 6.31885 11.3839 6.31885H16.0207C16.4082 6.31885 16.5693 6.81469 16.2558 7.04245L12.5046 9.76788C12.2943 9.92066 12.2063 10.1915 12.2866 10.4387L13.7194 14.8485C13.8392 15.2171 13.4174 15.5235 13.1039 15.2957L9.35267 12.5703C9.14238 12.4175 8.85762 12.4175 8.64733 12.5703L4.8961 15.2957C4.58262 15.5235 4.16083 15.2171 4.28057 14.8485L5.71341 10.4387C5.79373 10.1915 5.70574 9.92066 5.49544 9.76788L1.74422 7.04245C1.43073 6.81469 1.59184 6.31885 1.97933 6.31885H6.6161C6.87604 6.31885 7.10641 6.15147 7.18674 5.90426L8.61958 1.49443Z" stroke="white" stroke-opacity="0.36" stroke-width="0.2"/>
|
||||||
|
</g>
|
||||||
|
<path opacity="0.6" fill-rule="evenodd" clip-rule="evenodd" d="M9.47555 1.46353C9.40071 1.2332 9.20035 1.11804 9 1.11804V9L6.93514 6.10386C6.84752 6.17645 6.73556 6.21885 6.61612 6.21885H1.97935C1.73204 6.21885 1.5585 6.38044 1.50004 6.5765L9 9L5.61832 10.0988C5.65019 10.1969 5.65179 10.3048 5.61832 10.4078L4.18548 14.8176C4.11064 15.048 4.20503 15.2589 4.36711 15.3767L9 9V12.5557C9.10314 12.5557 9.20628 12.5876 9.29391 12.6512L13.0451 15.3767C13.2411 15.519 13.4708 15.4944 13.6329 15.3767L9 9L12.3817 10.0988C12.4136 10.0007 12.4757 9.91245 12.5634 9.84879L16.3146 7.12336C16.5064 6.98403 16.556 6.76443 16.5 6.5765L9 9L11.0649 6.10386C10.9936 6.0448 10.9384 5.96578 10.9084 5.87336L9.47555 1.46353Z" fill="url(#paint1_linear_855_1320)"/>
|
||||||
|
<g filter="url(#filter1_d_855_1320)">
|
||||||
|
<path d="M10.7182 5.93516L9.28532 1.52533C9.24043 1.38717 9.12028 1.31807 9.0001 1.31803V1.11803C9.20041 1.11807 9.4007 1.23324 9.47553 1.46353L10.9084 5.87336C10.9382 5.9652 10.9929 6.04383 11.0636 6.10276L10.9483 6.26684C10.8432 6.18328 10.7617 6.06929 10.7182 5.93516Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M6.6161 6.41885H1.97933C1.82922 6.41885 1.72441 6.51807 1.69055 6.63755L1.50167 6.57106C1.5617 6.37746 1.73431 6.21885 1.97933 6.21885H6.6161C6.73517 6.21885 6.8468 6.1767 6.9343 6.10453L7.05275 6.26597C6.9316 6.36263 6.77882 6.41885 6.6161 6.41885Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M5.80851 10.4696L4.37567 14.8794C4.33077 15.0176 4.3874 15.1442 4.48465 15.2148L4.3671 15.3766C4.20501 15.2589 4.11062 15.048 4.18546 14.8176L5.6183 10.4078C5.65177 10.3048 5.65017 10.1969 5.6183 10.0988L5.80851 10.037C5.85313 10.1743 5.85537 10.3254 5.80851 10.4696Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M9.41145 12.4894L13.1627 15.2148C13.2802 15.3003 13.4181 15.2855 13.5153 15.2148L13.6329 15.3766C13.4708 15.4944 13.241 15.519 13.0451 15.3766L9.29389 12.6512C9.20626 12.5876 9.10311 12.5557 8.99996 12.5557V12.3557C9.14436 12.3557 9.28877 12.4003 9.41145 12.4894Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M12.4458 9.68698L16.197 6.96155C16.3099 6.87953 16.3407 6.75115 16.3101 6.63984L16.4998 6.57587C16.5561 6.76393 16.5066 6.98387 16.3146 7.12336L12.5633 9.84878C12.4757 9.91244 12.4136 10.0007 12.3817 10.0988L12.1915 10.037C12.2361 9.89965 12.3231 9.7761 12.4458 9.68698Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_855_1320" x="0.478378" y="0.118034" width="17.0432" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_855_1320"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_855_1320" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_d_855_1320" x="0.501671" y="0.118034" width="17.02" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_855_1320"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_855_1320" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient id="paint0_radial_855_1320" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9 4) rotate(90) scale(8 10.5833)">
|
||||||
|
<stop stop-color="#FF9E9E"/>
|
||||||
|
<stop offset="1" stop-color="#FC5D5D"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint1_linear_855_1320" x1="5" y1="-1.5" x2="10" y2="14" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#FB9191"/>
|
||||||
|
<stop offset="1" stop-color="#EB4040"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.7 KiB |
44
public/icons/uncap/red.svg
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_d_553_227)">
|
||||||
|
<path d="M8.52447 1.46353C8.67415 1.00287 9.32585 1.00287 9.47553 1.46353L10.9084 5.87336C10.9753 6.07937 11.1673 6.21885 11.3839 6.21885H16.0207C16.505 6.21885 16.7064 6.83865 16.3146 7.12336L12.5633 9.84878C12.3881 9.9761 12.3148 10.2018 12.3817 10.4078L13.8145 14.8176C13.9642 15.2783 13.437 15.6613 13.0451 15.3766L9.29389 12.6512C9.11865 12.5239 8.88135 12.5239 8.70611 12.6512L4.95488 15.3766C4.56303 15.6613 4.03578 15.2783 4.18546 14.8176L5.6183 10.4078C5.68524 10.2018 5.61191 9.9761 5.43667 9.84878L1.68544 7.12336C1.29358 6.83866 1.49497 6.21885 1.97933 6.21885H6.6161C6.83272 6.21885 7.02469 6.07937 7.09163 5.87336L8.52447 1.46353Z" fill="url(#paint0_radial_553_227)"/>
|
||||||
|
<path d="M8.61958 1.49443C8.73932 1.1259 9.26068 1.1259 9.38042 1.49443L10.8133 5.90426C10.8936 6.15147 11.124 6.31885 11.3839 6.31885H16.0207C16.4082 6.31885 16.5693 6.81469 16.2558 7.04245L12.5046 9.76788C12.2943 9.92066 12.2063 10.1915 12.2866 10.4387L13.7194 14.8485C13.8392 15.2171 13.4174 15.5235 13.1039 15.2957L9.35267 12.5703C9.14238 12.4175 8.85762 12.4175 8.64733 12.5703L4.8961 15.2957C4.58262 15.5235 4.16083 15.2171 4.28057 14.8485L5.71341 10.4387C5.79373 10.1915 5.70574 9.92066 5.49544 9.76788L1.74422 7.04245C1.43073 6.81469 1.59184 6.31885 1.97933 6.31885H6.6161C6.87604 6.31885 7.10641 6.15147 7.18674 5.90426L8.61958 1.49443Z" stroke="white" stroke-opacity="0.36" stroke-width="0.2"/>
|
||||||
|
</g>
|
||||||
|
<path opacity="0.6" fill-rule="evenodd" clip-rule="evenodd" d="M9.47555 1.46353C9.40071 1.2332 9.20035 1.11804 9 1.11804V9L6.93514 6.10386C6.84752 6.17645 6.73556 6.21885 6.61612 6.21885H1.97935C1.73204 6.21885 1.5585 6.38044 1.50004 6.5765L9 9L5.61832 10.0988C5.65019 10.1969 5.65179 10.3048 5.61832 10.4078L4.18548 14.8176C4.11064 15.048 4.20503 15.2589 4.36711 15.3767L9 9V12.5557C9.10314 12.5557 9.20628 12.5876 9.29391 12.6512L13.0451 15.3767C13.2411 15.519 13.4708 15.4944 13.6329 15.3767L9 9L12.3817 10.0988C12.4136 10.0007 12.4757 9.91245 12.5634 9.84879L16.3146 7.12336C16.5064 6.98403 16.556 6.76443 16.5 6.5765L9 9L11.0649 6.10386C10.9936 6.0448 10.9384 5.96578 10.9084 5.87336L9.47555 1.46353Z" fill="url(#paint1_linear_553_227)"/>
|
||||||
|
<g filter="url(#filter1_d_553_227)">
|
||||||
|
<path d="M10.7182 5.93516L9.28532 1.52533C9.24043 1.38717 9.12028 1.31807 9.0001 1.31803V1.11803C9.20041 1.11807 9.4007 1.23324 9.47553 1.46353L10.9084 5.87336C10.9382 5.9652 10.9929 6.04383 11.0636 6.10276L10.9483 6.26684C10.8432 6.18328 10.7617 6.06929 10.7182 5.93516Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M6.6161 6.41885H1.97933C1.82922 6.41885 1.72441 6.51807 1.69055 6.63755L1.50167 6.57106C1.5617 6.37746 1.73431 6.21885 1.97933 6.21885H6.6161C6.73517 6.21885 6.8468 6.1767 6.9343 6.10453L7.05275 6.26597C6.9316 6.36263 6.77882 6.41885 6.6161 6.41885Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M5.80851 10.4696L4.37567 14.8794C4.33077 15.0176 4.3874 15.1442 4.48465 15.2148L4.3671 15.3766C4.20501 15.2589 4.11062 15.048 4.18546 14.8176L5.6183 10.4078C5.65177 10.3048 5.65017 10.1969 5.6183 10.0988L5.80851 10.037C5.85313 10.1743 5.85537 10.3254 5.80851 10.4696Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M9.41145 12.4894L13.1627 15.2148C13.2802 15.3003 13.4181 15.2855 13.5153 15.2148L13.6329 15.3766C13.4708 15.4944 13.241 15.519 13.0451 15.3766L9.29389 12.6512C9.20626 12.5876 9.10311 12.5557 8.99996 12.5557V12.3557C9.14436 12.3557 9.28877 12.4003 9.41145 12.4894Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M12.4458 9.68698L16.197 6.96155C16.3099 6.87953 16.3407 6.75115 16.3101 6.63984L16.4998 6.57587C16.5561 6.76393 16.5066 6.98387 16.3146 7.12336L12.5633 9.84878C12.4757 9.91244 12.4136 10.0007 12.3817 10.0988L12.1915 10.037C12.2361 9.89965 12.3231 9.7761 12.4458 9.68698Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_553_227" x="0.478378" y="0.118034" width="17.0432" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_553_227"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_553_227" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_d_553_227" x="0.501671" y="0.118034" width="17.02" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_553_227"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_553_227" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient id="paint0_radial_553_227" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9 6) rotate(90) scale(6 7.9375)">
|
||||||
|
<stop stop-color="#FEB2B2"/>
|
||||||
|
<stop offset="1" stop-color="#F05C5C"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint1_linear_553_227" x1="5" y1="-1.5" x2="10" y2="14" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#FCBCBC"/>
|
||||||
|
<stop offset="1" stop-color="#F45151"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.7 KiB |
44
public/icons/uncap/yellow-hover.svg
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_d_855_1306)">
|
||||||
|
<path d="M8.52447 1.46353C8.67415 1.00287 9.32585 1.00287 9.47553 1.46353L10.9084 5.87336C10.9753 6.07937 11.1673 6.21885 11.3839 6.21885H16.0207C16.505 6.21885 16.7064 6.83866 16.3146 7.12336L12.5633 9.84878C12.3881 9.9761 12.3148 10.2018 12.3817 10.4078L13.8145 14.8176C13.9642 15.2783 13.437 15.6613 13.0451 15.3766L9.29389 12.6512C9.11865 12.5239 8.88135 12.5239 8.70611 12.6512L4.95488 15.3766C4.56303 15.6613 4.03578 15.2783 4.18546 14.8176L5.6183 10.4078C5.68524 10.2018 5.61191 9.9761 5.43667 9.84878L1.68544 7.12336C1.29358 6.83866 1.49497 6.21885 1.97933 6.21885H6.6161C6.83272 6.21885 7.02469 6.07937 7.09163 5.87336L8.52447 1.46353Z" fill="url(#paint0_radial_855_1306)"/>
|
||||||
|
<path d="M9.38042 1.49443L10.8133 5.90426C10.8936 6.15147 11.124 6.31885 11.3839 6.31885H16.0207C16.4082 6.31885 16.5693 6.81469 16.2558 7.04245L12.5046 9.76788C12.2943 9.92066 12.2063 10.1915 12.2866 10.4387L13.7194 14.8485C13.8392 15.2171 13.4174 15.5235 13.1039 15.2957L9.35267 12.5703C9.14238 12.4175 8.85762 12.4175 8.64733 12.5703L4.8961 15.2957C4.58262 15.5235 4.16083 15.2171 4.28057 14.8485L5.71341 10.4387C5.79373 10.1915 5.70574 9.92066 5.49544 9.76788L1.74422 7.04245C1.43073 6.81469 1.59184 6.31885 1.97933 6.31885H6.6161C6.87604 6.31885 7.10641 6.15147 7.18674 5.90426L8.61958 1.49443C8.73932 1.1259 9.26068 1.1259 9.38042 1.49443Z" stroke="white" stroke-opacity="0.24" stroke-width="0.2"/>
|
||||||
|
</g>
|
||||||
|
<path opacity="0.3" fill-rule="evenodd" clip-rule="evenodd" d="M9.47555 1.46353C9.40071 1.2332 9.20035 1.11804 9 1.11804V9L6.93514 6.10386C6.84752 6.17644 6.73556 6.21885 6.61612 6.21885H1.97935C1.73204 6.21885 1.5585 6.38044 1.50004 6.5765L9 9L5.61832 10.0988C5.65019 10.1969 5.65179 10.3048 5.61832 10.4078L4.18548 14.8176C4.11064 15.048 4.20503 15.2589 4.36711 15.3767L9 9V12.5557C9.10314 12.5557 9.20628 12.5876 9.29391 12.6512L13.0451 15.3767C13.2411 15.519 13.4708 15.4944 13.6329 15.3767L9 9L12.3817 10.0988C12.4136 10.0007 12.4757 9.91245 12.5634 9.84879L16.3146 7.12336C16.5064 6.98403 16.556 6.76443 16.5 6.5765L9 9L11.0649 6.10386C10.9936 6.0448 10.9384 5.96578 10.9084 5.87336L9.47555 1.46353Z" fill="url(#paint1_linear_855_1306)"/>
|
||||||
|
<g filter="url(#filter1_d_855_1306)">
|
||||||
|
<path d="M10.7182 5.93517L9.28535 1.52534C9.24047 1.38718 9.12031 1.31808 9.00014 1.31804V1.11804C9.20045 1.11808 9.40074 1.23325 9.47557 1.46353L10.9084 5.87336C10.9383 5.96521 10.9929 6.04383 11.0636 6.10277L10.9484 6.26685C10.8432 6.18328 10.7618 6.0693 10.7182 5.93517Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M6.61614 6.41885H1.97937C1.82926 6.41885 1.72445 6.51807 1.69059 6.63755L1.50171 6.57107C1.56174 6.37747 1.73435 6.21885 1.97937 6.21885H6.61614C6.73521 6.21885 6.84683 6.17671 6.93434 6.10454L7.05278 6.26598C6.93164 6.36264 6.77886 6.41885 6.61614 6.41885Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M5.80855 10.4696L4.37571 14.8794C4.33081 15.0176 4.38744 15.1442 4.48469 15.2148L4.36714 15.3767C4.20505 15.2589 4.11066 15.048 4.1855 14.8176L5.61834 10.4078C5.65181 10.3048 5.65021 10.1969 5.61834 10.0988L5.80855 10.037C5.85317 10.1743 5.85541 10.3254 5.80855 10.4696Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M9.41149 12.4894L13.1627 15.2148C13.2803 15.3003 13.4181 15.2855 13.5154 15.2148L13.6329 15.3767C13.4709 15.4944 13.2411 15.519 13.0452 15.3767L9.29393 12.6512C9.2063 12.5876 9.10315 12.5557 9 12.5557V12.3557C9.1444 12.3557 9.28881 12.4003 9.41149 12.4894Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M12.4458 9.68698L16.197 6.96156C16.3099 6.87954 16.3408 6.75116 16.3101 6.63985L16.4998 6.57588C16.5562 6.76394 16.5066 6.98387 16.3146 7.12336L12.5634 9.84879C12.4758 9.91245 12.4136 10.0007 12.3817 10.0988L12.1915 10.037C12.2361 9.89966 12.3231 9.77611 12.4458 9.68698Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_855_1306" x="0.478374" y="0.118034" width="17.0433" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_855_1306"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_855_1306" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_d_855_1306" x="0.501709" y="0.118042" width="17.02" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_855_1306"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_855_1306" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient id="paint0_radial_855_1306" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9 7.5) rotate(90) scale(5.5 6.6878)">
|
||||||
|
<stop stop-color="#FFCCA8"/>
|
||||||
|
<stop offset="1" stop-color="#FFA96A"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint1_linear_855_1306" x1="5" y1="-1.5" x2="10" y2="14" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#FAAF7A"/>
|
||||||
|
<stop offset="1" stop-color="#DB742A"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.7 KiB |
44
public/icons/uncap/yellow.svg
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_d_553_27)">
|
||||||
|
<path d="M8.52447 1.46353C8.67415 1.00287 9.32585 1.00287 9.47553 1.46353L10.9084 5.87336C10.9753 6.07937 11.1673 6.21885 11.3839 6.21885H16.0207C16.505 6.21885 16.7064 6.83866 16.3146 7.12336L12.5633 9.84878C12.3881 9.9761 12.3148 10.2018 12.3817 10.4078L13.8145 14.8176C13.9642 15.2783 13.437 15.6613 13.0451 15.3766L9.29389 12.6512C9.11865 12.5239 8.88135 12.5239 8.70611 12.6512L4.95488 15.3766C4.56303 15.6613 4.03578 15.2783 4.18546 14.8176L5.6183 10.4078C5.68524 10.2018 5.61191 9.9761 5.43667 9.84878L1.68544 7.12336C1.29358 6.83866 1.49497 6.21885 1.97933 6.21885H6.6161C6.83272 6.21885 7.02469 6.07937 7.09163 5.87336L8.52447 1.46353Z" fill="url(#paint0_radial_553_27)"/>
|
||||||
|
<path d="M9.38042 1.49443L10.8133 5.90426C10.8936 6.15147 11.124 6.31885 11.3839 6.31885H16.0207C16.4082 6.31885 16.5693 6.81469 16.2558 7.04245L12.5046 9.76788C12.2943 9.92066 12.2063 10.1915 12.2866 10.4387L13.7194 14.8485C13.8392 15.2171 13.4174 15.5235 13.1039 15.2957L9.35267 12.5703C9.14238 12.4175 8.85762 12.4175 8.64733 12.5703L4.8961 15.2957C4.58262 15.5235 4.16083 15.2171 4.28057 14.8485L5.71341 10.4387C5.79373 10.1915 5.70574 9.92066 5.49544 9.76788L1.74422 7.04245C1.43073 6.81469 1.59184 6.31885 1.97933 6.31885H6.6161C6.87604 6.31885 7.10641 6.15147 7.18674 5.90426L8.61958 1.49443C8.73932 1.1259 9.26068 1.1259 9.38042 1.49443Z" stroke="white" stroke-opacity="0.24" stroke-width="0.2"/>
|
||||||
|
</g>
|
||||||
|
<path opacity="0.3" fill-rule="evenodd" clip-rule="evenodd" d="M9.47555 1.46353C9.40071 1.2332 9.20035 1.11804 9 1.11804V9L6.93514 6.10386C6.84752 6.17645 6.73556 6.21885 6.61612 6.21885H1.97935C1.73204 6.21885 1.5585 6.38044 1.50004 6.5765L9 9L5.61832 10.0988C5.65019 10.1969 5.65179 10.3048 5.61832 10.4078L4.18548 14.8176C4.11064 15.048 4.20503 15.2589 4.36711 15.3767L9 9V12.5557C9.10314 12.5557 9.20628 12.5876 9.29391 12.6512L13.0451 15.3767C13.2411 15.519 13.4708 15.4944 13.6329 15.3767L9 9L12.3817 10.0988C12.4136 10.0007 12.4757 9.91245 12.5634 9.84879L16.3146 7.12336C16.5064 6.98403 16.556 6.76443 16.5 6.5765L9 9L11.0649 6.10386C10.9936 6.0448 10.9384 5.96578 10.9084 5.87336L9.47555 1.46353Z" fill="url(#paint1_linear_553_27)"/>
|
||||||
|
<g filter="url(#filter1_d_553_27)">
|
||||||
|
<path d="M10.7182 5.93517L9.28535 1.52534C9.24047 1.38718 9.12031 1.31808 9.00014 1.31804V1.11804C9.20045 1.11808 9.40074 1.23325 9.47557 1.46353L10.9084 5.87336C10.9383 5.96521 10.9929 6.04383 11.0636 6.10277L10.9484 6.26685C10.8432 6.18328 10.7618 6.0693 10.7182 5.93517Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M6.61614 6.41885H1.97937C1.82926 6.41885 1.72445 6.51807 1.69059 6.63755L1.50171 6.57107C1.56174 6.37747 1.73435 6.21885 1.97937 6.21885H6.61614C6.73521 6.21885 6.84683 6.17671 6.93434 6.10454L7.05278 6.26598C6.93164 6.36264 6.77886 6.41885 6.61614 6.41885Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M5.80855 10.4696L4.37571 14.8794C4.33081 15.0176 4.38744 15.1442 4.48469 15.2148L4.36714 15.3767C4.20505 15.2589 4.11066 15.048 4.1855 14.8176L5.61834 10.4078C5.65181 10.3048 5.65021 10.1969 5.61834 10.0988L5.80855 10.037C5.85317 10.1743 5.85541 10.3254 5.80855 10.4696Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M9.41149 12.4894L13.1627 15.2148C13.2803 15.3003 13.4181 15.2855 13.5154 15.2148L13.6329 15.3767C13.4709 15.4944 13.2411 15.519 13.0452 15.3767L9.29393 12.6512C9.2063 12.5876 9.10315 12.5557 9 12.5557V12.3557C9.1444 12.3557 9.28881 12.4003 9.41149 12.4894Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
<path d="M12.4458 9.68698L16.197 6.96156C16.3099 6.87954 16.3408 6.75116 16.3101 6.63985L16.4998 6.57588C16.5562 6.76394 16.5066 6.98387 16.3146 7.12336L12.5634 9.84879C12.4758 9.91245 12.4136 10.0007 12.3817 10.0988L12.1915 10.037C12.2361 9.89966 12.3231 9.77611 12.4458 9.68698Z" fill="black" fill-opacity="0.12" shape-rendering="crispEdges"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_553_27" x="0.478374" y="0.118034" width="17.0433" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_553_27"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_553_27" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_d_553_27" x="0.501709" y="0.118042" width="17.02" height="16.3564" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="0.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_553_27"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_553_27" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient id="paint0_radial_553_27" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9 7.5) rotate(90) scale(5.5 6.6878)">
|
||||||
|
<stop stop-color="#FED2B2"/>
|
||||||
|
<stop offset="1" stop-color="#FFB884"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint1_linear_553_27" x1="5" y1="-1.5" x2="10" y2="14" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#FCD7BC"/>
|
||||||
|
<stop offset="1" stop-color="#F49651"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.7 KiB |
|
|
@ -27,3 +27,7 @@ $font-small: 12px;
|
||||||
$font-regular: 14px;
|
$font-regular: 14px;
|
||||||
$font-large: 18px;
|
$font-large: 18px;
|
||||||
$font-xlarge: 21px;
|
$font-xlarge: 21px;
|
||||||
|
|
||||||
|
// Scale factors
|
||||||
|
$scale-wide: scale(1.05, 1.05);
|
||||||
|
$scale-tall: scale(1.012, 1.012);
|
||||||
2
types/Character.d.ts
vendored
|
|
@ -21,6 +21,7 @@ interface Character {
|
||||||
}
|
}
|
||||||
uncap: {
|
uncap: {
|
||||||
flb: boolean
|
flb: boolean
|
||||||
|
ulb: boolean
|
||||||
}
|
}
|
||||||
race: {
|
race: {
|
||||||
race1: number
|
race1: number
|
||||||
|
|
@ -31,4 +32,5 @@ interface Character {
|
||||||
proficiency2: number
|
proficiency2: number
|
||||||
}
|
}
|
||||||
position?: number
|
position?: number
|
||||||
|
special: boolean
|
||||||
}
|
}
|
||||||
3
types/GridCharacter.d.ts
vendored
|
|
@ -1,5 +1,6 @@
|
||||||
interface GridCharacter {
|
interface GridCharacter {
|
||||||
id: string
|
id: string
|
||||||
position: number | null
|
position: number
|
||||||
character: Character
|
character: Character
|
||||||
|
uncap_level: number
|
||||||
}
|
}
|
||||||
3
types/GridSummon.d.ts
vendored
|
|
@ -2,6 +2,7 @@ interface GridSummon {
|
||||||
id: string
|
id: string
|
||||||
main: boolean
|
main: boolean
|
||||||
friend: boolean
|
friend: boolean
|
||||||
position: number | null
|
position: number
|
||||||
summon: Summon
|
summon: Summon
|
||||||
|
uncap_level: number
|
||||||
}
|
}
|
||||||
3
types/GridWeapon.d.ts
vendored
|
|
@ -1,6 +1,7 @@
|
||||||
interface GridWeapon {
|
interface GridWeapon {
|
||||||
id: string
|
id: string
|
||||||
mainhand: boolean
|
mainhand: boolean
|
||||||
position: number | null
|
position: number
|
||||||
weapon: Weapon
|
weapon: Weapon
|
||||||
|
uncap_level: number
|
||||||
}
|
}
|
||||||
|
|
@ -58,12 +58,23 @@ class Api {
|
||||||
return axios.get(url)
|
return axios.get(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
check(resource: string, value: string) {
|
check(resource: 'username'|'email', value: string) {
|
||||||
const resourceUrl = `${this.url}/check/${resource}`
|
const resourceUrl = `${this.url}/check/${resource}`
|
||||||
return axios.post(resourceUrl, {
|
return axios.post(resourceUrl, {
|
||||||
[resource]: value
|
[resource]: value
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateUncap(resource: 'character'|'weapon'|'summon', id: string, value: number) {
|
||||||
|
const pluralized = resource + 's'
|
||||||
|
const resourceUrl = `${this.url}/${pluralized}/update_uncap`
|
||||||
|
return axios.post(resourceUrl, {
|
||||||
|
[resource]: {
|
||||||
|
id: id,
|
||||||
|
uncap_level: value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const api: Api = new Api({ url: process.env.NEXT_PUBLIC_SIERO_API_URL || 'https://localhost:3000/api/v1'})
|
const api: Api = new Api({ url: process.env.NEXT_PUBLIC_SIERO_API_URL || 'https://localhost:3000/api/v1'})
|
||||||
|
|
|
||||||