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 { AxiosResponse } from 'axios'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
import CharacterUnit from '~components/CharacterUnit'
|
||||
import SearchModal from '~components/SearchModal'
|
||||
|
||||
import api from '~utils/api'
|
||||
import './index.scss'
|
||||
|
||||
// GridType
|
||||
export enum GridType {
|
||||
Class,
|
||||
Character,
|
||||
|
|
@ -13,67 +20,206 @@ export enum GridType {
|
|||
Summon
|
||||
}
|
||||
|
||||
// Props
|
||||
interface Props {
|
||||
userId?: string
|
||||
grid: GridArray<Character>
|
||||
partyId?: string
|
||||
characters: GridArray<GridCharacter>
|
||||
editable: boolean
|
||||
exists: boolean
|
||||
onSelect: (type: GridType, character: Character, position: number) => void
|
||||
createParty: () => Promise<AxiosResponse<any, any>>
|
||||
pushHistory?: (path: string) => void
|
||||
}
|
||||
|
||||
const CharacterGrid = (props: Props) => {
|
||||
const { open, openModal, closeModal } = useModal()
|
||||
const [searchPosition, setSearchPosition] = useState(0)
|
||||
|
||||
// Constants
|
||||
const numCharacters: number = 5
|
||||
|
||||
function isCharacter(object: Character | Weapon | Summon): object is Character {
|
||||
// There aren't really any unique fields here
|
||||
return (object as Character).gender !== undefined
|
||||
}
|
||||
// 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 [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) {
|
||||
setSearchPosition(position)
|
||||
setItemPositionForSearch(position)
|
||||
openModal()
|
||||
}
|
||||
|
||||
function receiveCharacter(character: Character, position: number) {
|
||||
props.onSelect(GridType.Character, character, position)
|
||||
}
|
||||
function receiveCharacterFromSearch(object: Character | Weapon | Summon, position: number) {
|
||||
const character = object as Character
|
||||
|
||||
function sendData(object: Character | Weapon | Summon, position: number) {
|
||||
if (isCharacter(object)) {
|
||||
receiveCharacter(object, position)
|
||||
if (!partyId) {
|
||||
props.createParty()
|
||||
.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 (
|
||||
<div className="CharacterGrid">
|
||||
<ul id="grid_characters">
|
||||
{
|
||||
Array.from(Array(numCharacters)).map((x, i) => {
|
||||
return (
|
||||
<li key={`grid_unit_${i}`} >
|
||||
<CharacterUnit
|
||||
onClick={() => { openSearchModal(i) }}
|
||||
editable={props.editable}
|
||||
position={i}
|
||||
character={props.grid[i]}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
{Array.from(Array(numCharacters)).map((x, i) => {
|
||||
return (
|
||||
<li key={`grid_unit_${i}`} >
|
||||
<CharacterUnit
|
||||
gridCharacter={props.characters[i]}
|
||||
editable={props.editable}
|
||||
position={i}
|
||||
onClick={() => { openSearchModal(i) }}
|
||||
updateUncap={initiateUncapUpdate}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
|
||||
{open ? (
|
||||
<SearchModal
|
||||
grid={props.grid}
|
||||
close={closeModal}
|
||||
send={sendData}
|
||||
fromPosition={searchPosition}
|
||||
object="characters"
|
||||
placeholderText="Search for a character..."
|
||||
/>
|
||||
) : null}
|
||||
<SearchModal
|
||||
grid={searchGrid}
|
||||
close={closeModal}
|
||||
send={receiveCharacterFromSearch}
|
||||
fromPosition={itemPositionForSearch}
|
||||
object="characters"
|
||||
placeholderText="Search for a character..."
|
||||
/>
|
||||
) : null}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-shadow: rgba(0, 0, 0, 0.14) 0px 0px 14px;
|
||||
cursor: pointer;
|
||||
transform: scale(1.1, 1.1);
|
||||
transform: $scale-tall;
|
||||
}
|
||||
|
||||
.CharacterUnit.filled h3 {
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@ import React, { useEffect, useState } from 'react'
|
|||
import classnames from 'classnames'
|
||||
|
||||
import UncapIndicator from '~components/UncapIndicator'
|
||||
|
||||
import PlusIcon from '~public/icons/plus.svg'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
interface Props {
|
||||
onClick: () => void
|
||||
character: Character | undefined
|
||||
gridCharacter: GridCharacter | undefined
|
||||
position: number
|
||||
editable: boolean
|
||||
onClick: () => void
|
||||
updateUncap: (id: string, position: number, uncap: number) => void
|
||||
}
|
||||
|
||||
const CharacterUnit = (props: Props) => {
|
||||
|
|
@ -20,27 +20,32 @@ const CharacterUnit = (props: Props) => {
|
|||
const classes = classnames({
|
||||
CharacterUnit: true,
|
||||
'editable': props.editable,
|
||||
'filled': (props.character !== undefined)
|
||||
'filled': (props.gridCharacter !== undefined)
|
||||
})
|
||||
|
||||
const character = props.character
|
||||
const gridCharacter = props.gridCharacter
|
||||
const character = gridCharacter?.character
|
||||
|
||||
useEffect(() => {
|
||||
generateImageUrl()
|
||||
})
|
||||
|
||||
|
||||
function generateImageUrl() {
|
||||
let imgSrc = ""
|
||||
|
||||
if (props.character) {
|
||||
const character = props.character!
|
||||
if (props.gridCharacter) {
|
||||
const character = props.gridCharacter.character!
|
||||
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/chara-main/${character.granblue_id}_01.jpg`
|
||||
}
|
||||
|
||||
setImageUrl(imgSrc)
|
||||
}
|
||||
|
||||
function passUncapData(uncap: number) {
|
||||
if (props.gridCharacter)
|
||||
props.updateUncap(props.gridCharacter.id, props.position, uncap)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={classes}>
|
||||
|
|
@ -48,11 +53,15 @@ const CharacterUnit = (props: Props) => {
|
|||
<img alt={character?.name.en} className="grid_image" src={imageUrl} />
|
||||
{ (props.editable) ? <span className='icon'><PlusIcon /></span> : '' }
|
||||
</div>
|
||||
<UncapIndicator
|
||||
type="character"
|
||||
flb={character?.uncap.flb || false}
|
||||
uncapLevel={(character?.rarity == 2) ? 3 : 4}
|
||||
/>
|
||||
{ (gridCharacter && character) ?
|
||||
<UncapIndicator
|
||||
type="character"
|
||||
flb={character.uncap.flb || false}
|
||||
ulb={character.uncap.ulb || false}
|
||||
uncapLevel={gridCharacter.uncap_level}
|
||||
updateUncap={passUncapData}
|
||||
special={character.special}
|
||||
/> : '' }
|
||||
<h3 className="CharacterName">{character?.name.en}</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,12 +12,13 @@ export enum GridType {
|
|||
|
||||
// Props
|
||||
interface Props {
|
||||
grid: GridArray<Summon>
|
||||
grid: GridArray<GridSummon>
|
||||
editable: boolean
|
||||
exists: boolean
|
||||
found?: boolean
|
||||
offset: number
|
||||
onClick: (position: number) => void
|
||||
updateUncap: (id: string, position: number, uncap: number) => void
|
||||
}
|
||||
|
||||
const ExtraSummons = (props: Props) => {
|
||||
|
|
@ -32,11 +33,12 @@ const ExtraSummons = (props: Props) => {
|
|||
return (
|
||||
<li key={`grid_unit_${i}`} >
|
||||
<SummonUnit
|
||||
onClick={() => { props.onClick(props.offset + i) }}
|
||||
editable={props.editable}
|
||||
position={props.offset + i}
|
||||
unitType={1}
|
||||
summon={props.grid[props.offset + i]}
|
||||
gridSummon={props.grid[props.offset + i]}
|
||||
onClick={() => { props.onClick(props.offset + i) }}
|
||||
updateUncap={props.updateUncap}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ export enum GridType {
|
|||
|
||||
// Props
|
||||
interface Props {
|
||||
grid: GridArray<Weapon>
|
||||
grid: GridArray<GridWeapon>
|
||||
editable: boolean
|
||||
exists: boolean
|
||||
found?: boolean
|
||||
offset: number
|
||||
onClick: (position: number) => void
|
||||
updateUncap: (id: string, position: number, uncap: number) => void
|
||||
}
|
||||
|
||||
const ExtraWeapons = (props: Props) => {
|
||||
|
|
@ -34,10 +34,11 @@ const ExtraWeapons = (props: Props) => {
|
|||
<li key={`grid_unit_${i}`} >
|
||||
<WeaponUnit
|
||||
editable={props.editable}
|
||||
onClick={() => { props.onClick(props.offset + i)}}
|
||||
position={props.offset + i}
|
||||
unitType={1}
|
||||
weapon={props.grid[props.offset + i]}
|
||||
gridWeapon={props.grid[props.offset + i]}
|
||||
onClick={() => { props.onClick(props.offset + i)}}
|
||||
updateUncap={props.updateUncap}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
import React, { ChangeEvent, useEffect, useState } from 'react'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useCookies } from 'react-cookie'
|
||||
import api from '~utils/api'
|
||||
|
||||
// UI Elements
|
||||
import PartySegmentedControl from '~components/PartySegmentedControl'
|
||||
|
||||
// Grids
|
||||
import WeaponGrid from '~components/WeaponGrid'
|
||||
import SummonGrid from '~components/SummonGrid'
|
||||
import CharacterGrid from '~components/CharacterGrid'
|
||||
|
||||
import api from '~utils/api'
|
||||
import './index.scss'
|
||||
|
||||
// GridType
|
||||
enum GridType {
|
||||
Class,
|
||||
|
|
@ -17,96 +16,58 @@ enum GridType {
|
|||
Weapon,
|
||||
Summon
|
||||
}
|
||||
export { GridType }
|
||||
|
||||
import './index.scss'
|
||||
|
||||
// Props
|
||||
interface Props {
|
||||
partyId?: string
|
||||
mainWeapon?: Weapon
|
||||
mainSummon?: Summon
|
||||
friendSummon?: Summon
|
||||
characters?: GridArray<Character>
|
||||
weapons?: GridArray<Weapon>
|
||||
summons?: GridArray<Summon>
|
||||
mainWeapon?: GridWeapon
|
||||
mainSummon?: GridSummon
|
||||
friendSummon?: GridSummon
|
||||
characters?: GridArray<GridCharacter>
|
||||
weapons?: GridArray<GridWeapon>
|
||||
summons?: GridArray<GridSummon>
|
||||
extra: boolean
|
||||
editable: boolean
|
||||
exists: boolean
|
||||
pushHistory?: (path: string) => void
|
||||
}
|
||||
|
||||
const Party = (props: Props) => {
|
||||
// Cookies
|
||||
const [cookies, _] = useCookies(['user'])
|
||||
|
||||
const headers = (cookies.user != null) ? {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${cookies.user.access_token}`
|
||||
}
|
||||
} : {}
|
||||
|
||||
// Grid data
|
||||
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>()
|
||||
|
||||
// Set up states
|
||||
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 [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>) {
|
||||
setExtra(event.target.checked)
|
||||
}
|
||||
|
||||
// Methods: Navigating with segmented control
|
||||
function segmentClicked(event: React.ChangeEvent<HTMLInputElement>) {
|
||||
switch(event.target.value) {
|
||||
case 'class':
|
||||
|
|
@ -126,166 +87,66 @@ const Party = (props: Props) => {
|
|||
}
|
||||
}
|
||||
|
||||
function itemSelected(type: GridType, item: Character | Weapon | Summon, position: number) {
|
||||
if (!partyId) {
|
||||
createParty()
|
||||
.then(response => {
|
||||
return response.data.party
|
||||
})
|
||||
.then(party => {
|
||||
if (props.pushHistory) {
|
||||
props.pushHistory(`/p/${party.shortcode}`)
|
||||
}
|
||||
// Render: JSX components
|
||||
const navigation = (
|
||||
<PartySegmentedControl
|
||||
extra={extra}
|
||||
editable={props.editable}
|
||||
selectedTab={currentTab}
|
||||
onClick={segmentClicked}
|
||||
onCheckboxChange={checkboxChanged}
|
||||
/>
|
||||
)
|
||||
|
||||
return party.id
|
||||
})
|
||||
.then(partyId => {
|
||||
setPartyId(partyId)
|
||||
saveItem(partyId, type, item, position)
|
||||
})
|
||||
} else {
|
||||
saveItem(partyId, type, item, position)
|
||||
}
|
||||
}
|
||||
const weaponGrid = (
|
||||
<WeaponGrid
|
||||
partyId={props.partyId}
|
||||
mainhand={props.mainWeapon}
|
||||
weapons={props.weapons || {}}
|
||||
extra={extra}
|
||||
editable={props.editable}
|
||||
createParty={createParty}
|
||||
pushHistory={props.pushHistory}
|
||||
/>
|
||||
)
|
||||
|
||||
async function createParty() {
|
||||
const body = (!cookies.user) ? {
|
||||
party: {
|
||||
is_extra: extra
|
||||
}
|
||||
} : {
|
||||
party: {
|
||||
user_id: cookies.user.userId,
|
||||
is_extra: extra
|
||||
}
|
||||
}
|
||||
const summonGrid = (
|
||||
<SummonGrid
|
||||
partyId={props.partyId}
|
||||
mainSummon={props.mainSummon}
|
||||
friendSummon={props.friendSummon}
|
||||
summons={props.summons || {}}
|
||||
editable={props.editable}
|
||||
createParty={createParty}
|
||||
pushHistory={props.pushHistory}
|
||||
/>
|
||||
)
|
||||
|
||||
return await api.endpoints.parties.create(body, headers)
|
||||
}
|
||||
const characterGrid = (
|
||||
<CharacterGrid
|
||||
partyId={props.partyId}
|
||||
characters={props.characters || {}}
|
||||
editable={props.editable}
|
||||
createParty={createParty}
|
||||
pushHistory={props.pushHistory}
|
||||
/>
|
||||
)
|
||||
|
||||
function saveItem(partyId: string, type: GridType, item: Character | Weapon | Summon, position: number) {
|
||||
switch(type) {
|
||||
case GridType.Class:
|
||||
saveClass()
|
||||
break
|
||||
const currentGrid = () => {
|
||||
switch(currentTab) {
|
||||
case GridType.Character:
|
||||
const character = item as Character
|
||||
saveCharacter(character, position, partyId)
|
||||
.then(() => {
|
||||
storeCharacter(character, position)
|
||||
})
|
||||
break
|
||||
return characterGrid
|
||||
case GridType.Weapon:
|
||||
const weapon = item as Weapon
|
||||
saveWeapon(weapon, position, partyId)
|
||||
.then(() => {
|
||||
storeWeapon(weapon, position)
|
||||
})
|
||||
break
|
||||
return weaponGrid
|
||||
case GridType.Summon:
|
||||
const summon = item as Summon
|
||||
saveSummon(summon, position, partyId)
|
||||
.then(() => {
|
||||
storeSummon(summon, position)
|
||||
})
|
||||
break
|
||||
return summonGrid
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
extra={extra}
|
||||
editable={props.editable}
|
||||
selectedTab={currentTab}
|
||||
onClick={segmentClicked}
|
||||
onCheckboxChange={checkboxChanged}
|
||||
/>
|
||||
|
||||
{
|
||||
(() => {
|
||||
switch(currentTab) {
|
||||
case GridType.Character:
|
||||
return characterGrid
|
||||
case GridType.Weapon:
|
||||
return weaponGrid
|
||||
case GridType.Summon:
|
||||
return summonGrid
|
||||
}
|
||||
})()
|
||||
}
|
||||
{ navigation }
|
||||
{ currentGrid() }
|
||||
</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 SearchModal from '~components/SearchModal'
|
||||
import ExtraSummons from '~components/ExtraSummons'
|
||||
import SummonUnit from '~components/SummonUnit'
|
||||
import { AxiosResponse } from 'axios'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
import SearchModal from '~components/SearchModal'
|
||||
import SummonUnit from '~components/SummonUnit'
|
||||
import ExtraSummons from '~components/ExtraSummons'
|
||||
|
||||
import api from '~utils/api'
|
||||
import './index.scss'
|
||||
|
||||
// GridType
|
||||
|
|
@ -17,106 +23,262 @@ export enum GridType {
|
|||
|
||||
// Props
|
||||
interface Props {
|
||||
userId?: string
|
||||
partyId?: string
|
||||
main?: Summon | undefined
|
||||
friend?: Summon | undefined
|
||||
grid: GridArray<Summon>
|
||||
mainSummon: GridSummon | undefined
|
||||
friendSummon: GridSummon | undefined
|
||||
summons: GridArray<GridSummon>
|
||||
editable: boolean
|
||||
exists: boolean
|
||||
found?: boolean
|
||||
onSelect: (type: GridType, summon: Summon, position: number) => void
|
||||
createParty: () => Promise<AxiosResponse<any, any>>
|
||||
pushHistory?: (path: string) => void
|
||||
}
|
||||
|
||||
const SummonGrid = (props: Props) => {
|
||||
const { open, openModal, closeModal } = useModal()
|
||||
const [searchPosition, setSearchPosition] = useState(0)
|
||||
|
||||
// Constants
|
||||
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) {
|
||||
setSearchPosition(position)
|
||||
setItemPositionForSearch(position)
|
||||
openModal()
|
||||
}
|
||||
|
||||
function receiveSummon(summon: Summon, position: number) {
|
||||
props.onSelect(GridType.Summon, summon, position)
|
||||
}
|
||||
function receiveSummonFromSearch(object: Character | Weapon | Summon, position: number) {
|
||||
const summon = object as Summon
|
||||
|
||||
function sendData(object: Character | Weapon | Summon, position: number) {
|
||||
if (isSummon(object)) {
|
||||
receiveSummon(object, position)
|
||||
if (!partyId) {
|
||||
props.createParty()
|
||||
.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 {
|
||||
// There aren't really any unique fields here
|
||||
return (object as Summon).granblue_id !== undefined
|
||||
async function saveSummon(partyId: string, summon: Summon, position: number) {
|
||||
let uncapLevel = 3
|
||||
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)
|
||||
}
|
||||
|
||||
function storeGridSummon(gridSummon: GridSummon) {
|
||||
if (gridSummon.position == -1) {
|
||||
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="Label">Main Summon</div>
|
||||
<SummonUnit
|
||||
gridSummon={props.mainSummon}
|
||||
editable={props.editable}
|
||||
key="grid_main_summon"
|
||||
position={-1}
|
||||
unitType={0}
|
||||
onClick={() => { openSearchModal(-1) }}
|
||||
updateUncap={initiateUncapUpdate}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
const friendSummonElement = (
|
||||
<div className="LabeledUnit">
|
||||
<div className="Label">Friend Summon</div>
|
||||
<SummonUnit
|
||||
gridSummon={props.friendSummon}
|
||||
editable={props.editable}
|
||||
key="grid_friend_summon"
|
||||
position={6}
|
||||
unitType={2}
|
||||
onClick={() => { openSearchModal(6) }}
|
||||
updateUncap={initiateUncapUpdate}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
const summonGridElement = (
|
||||
<div id="LabeledGrid">
|
||||
<div className="Label">Summons</div>
|
||||
<ul id="grid_summons">
|
||||
{Array.from(Array(numSummons)).map((x, i) => {
|
||||
return (<li key={`grid_unit_${i}`} >
|
||||
<SummonUnit
|
||||
gridSummon={props.summons[i]}
|
||||
editable={props.editable}
|
||||
position={i}
|
||||
unitType={1}
|
||||
onClick={() => { openSearchModal(i) }}
|
||||
updateUncap={initiateUncapUpdate}
|
||||
/>
|
||||
</li>)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
const subAuraSummonElement = (
|
||||
<ExtraSummons
|
||||
grid={props.summons}
|
||||
editable={props.editable}
|
||||
exists={false}
|
||||
offset={numSummons}
|
||||
onClick={openSearchModal}
|
||||
updateUncap={initiateUncapUpdate}
|
||||
/>
|
||||
)
|
||||
return (
|
||||
<div>
|
||||
<div className="SummonGrid">
|
||||
<div className="LabeledUnit">
|
||||
<div className="Label">Main Summon</div>
|
||||
<SummonUnit
|
||||
onClick={() => { openSearchModal(0) }}
|
||||
editable={props.editable}
|
||||
key="grid_main_summon"
|
||||
position={-1}
|
||||
unitType={0}
|
||||
summon={props.main}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="LabeledUnit">
|
||||
<div className="Label">Friend Summon</div>
|
||||
<SummonUnit
|
||||
onClick={() => { openSearchModal(6) }}
|
||||
editable={props.editable}
|
||||
key="grid_friend_summon"
|
||||
position={6}
|
||||
unitType={2}
|
||||
summon={props.friend}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="LabeledGrid">
|
||||
<div className="Label">Summons</div>
|
||||
<ul id="grid_summons">
|
||||
{
|
||||
Array.from(Array(numSummons)).map((x, i) => {
|
||||
return (
|
||||
<li key={`grid_unit_${i}`} >
|
||||
<SummonUnit
|
||||
onClick={() => { openSearchModal(i) }}
|
||||
editable={props.editable}
|
||||
position={i}
|
||||
unitType={1}
|
||||
summon={props.grid[i]}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
{ mainSummonElement }
|
||||
{ friendSummonElement }
|
||||
{ summonGridElement }
|
||||
</div>
|
||||
|
||||
<ExtraSummons
|
||||
onClick={openSearchModal}
|
||||
grid={props.grid}
|
||||
editable={props.editable}
|
||||
exists={false}
|
||||
offset={numSummons}
|
||||
/>
|
||||
{ subAuraSummonElement }
|
||||
|
||||
{open ? (
|
||||
<SearchModal
|
||||
grid={props.grid}
|
||||
grid={searchGrid}
|
||||
close={closeModal}
|
||||
send={sendData}
|
||||
fromPosition={searchPosition}
|
||||
send={receiveSummonFromSearch}
|
||||
fromPosition={itemPositionForSearch}
|
||||
object="summons"
|
||||
placeholderText="Search for a summon..."
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -33,7 +33,12 @@
|
|||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-shadow: rgba(0, 0, 0, 0.14) 0px 0px 14px;
|
||||
cursor: pointer;
|
||||
transform: scale(1.1, 1.1);
|
||||
transform: $scale-wide;
|
||||
}
|
||||
|
||||
&.main.editable .SummonImage:hover,
|
||||
&.friend.editable .SummonImage:hover {
|
||||
transform: $scale-tall;
|
||||
}
|
||||
|
||||
&.filled h3 {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
|
||||
import classnames from 'classnames'
|
||||
|
||||
import UncapIndicator from '~components/UncapIndicator'
|
||||
|
||||
import PlusIcon from '~public/icons/plus.svg'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
interface Props {
|
||||
onClick: () => void
|
||||
summon: Summon | undefined
|
||||
updateUncap: (id: string, position: number, uncap: number) => void
|
||||
gridSummon: GridSummon | undefined
|
||||
position: number
|
||||
editable: boolean
|
||||
unitType: 0 | 1 | 2
|
||||
|
|
@ -25,10 +24,11 @@ const SummonUnit = (props: Props) => {
|
|||
'grid': props.unitType == 1,
|
||||
'friend': props.unitType == 2,
|
||||
'editable': props.editable,
|
||||
'filled': (props.summon !== undefined)
|
||||
'filled': (props.gridSummon !== undefined)
|
||||
})
|
||||
|
||||
const summon = props.summon
|
||||
const gridSummon = props.gridSummon
|
||||
const summon = gridSummon?.summon
|
||||
|
||||
useEffect(() => {
|
||||
generateImageUrl()
|
||||
|
|
@ -36,8 +36,8 @@ const SummonUnit = (props: Props) => {
|
|||
|
||||
function generateImageUrl() {
|
||||
let imgSrc = ""
|
||||
if (props.summon) {
|
||||
const summon = props.summon!
|
||||
if (props.gridSummon) {
|
||||
const summon = props.gridSummon.summon!
|
||||
|
||||
// Generate the correct source for the summon
|
||||
if (props.unitType == 0 || props.unitType == 2)
|
||||
|
|
@ -49,6 +49,11 @@ const SummonUnit = (props: Props) => {
|
|||
setImageUrl(imgSrc)
|
||||
}
|
||||
|
||||
function passUncapData(uncap: number) {
|
||||
if (props.gridSummon)
|
||||
props.updateUncap(props.gridSummon.id, uncap)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={classes}>
|
||||
|
|
@ -56,12 +61,15 @@ const SummonUnit = (props: Props) => {
|
|||
<img alt={summon?.name.en} className="grid_image" src={imageUrl} />
|
||||
{ (props.editable) ? <span className='icon'><PlusIcon /></span> : '' }
|
||||
</div>
|
||||
{ (gridSummon) ?
|
||||
<UncapIndicator
|
||||
type="summon"
|
||||
ulb={summon?.uncap.ulb || false}
|
||||
ulb={summon?.uncap.ulb || false}
|
||||
flb={summon?.uncap.flb || false}
|
||||
uncapLevel={3}
|
||||
/>
|
||||
uncapLevel={gridSummon?.uncap_level}
|
||||
updateUncap={passUncapData}
|
||||
special={false}
|
||||
/> : '' }
|
||||
<h3 className="SummonName">{summon?.name.en}</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,20 +12,20 @@ interface Props {
|
|||
const ToggleSwitch: React.FC<Props> = (props: Props) => {
|
||||
return (
|
||||
<div className="toggle-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={props.checked}
|
||||
disabled={!props.editable}
|
||||
className="toggle-switch-checkbox"
|
||||
name={props.name}
|
||||
id={props.name}
|
||||
onChange={props.onChange}
|
||||
/>
|
||||
<label className="toggle-switch-label" htmlFor={props.name}>
|
||||
<span className="toggle-switch-switch" />
|
||||
</label>
|
||||
<input
|
||||
className="toggle-switch-checkbox"
|
||||
name={props.name}
|
||||
id={props.name}
|
||||
type="checkbox"
|
||||
checked={props.checked}
|
||||
disabled={!props.editable}
|
||||
onChange={props.onChange}
|
||||
/>
|
||||
<label className="toggle-switch-label" htmlFor={props.name}>
|
||||
<span className="toggle-switch-switch" />
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default ToggleSwitch
|
||||
|
|
@ -7,4 +7,8 @@
|
|||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +1,94 @@
|
|||
import React from 'react'
|
||||
import classnames from 'classnames'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import UncapStar from '~components/UncapStar'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
|
||||
interface Props {
|
||||
type: 'character' | 'weapon' | 'summon'
|
||||
rarity?: number
|
||||
uncapLevel: number
|
||||
flb: boolean
|
||||
ulb?: boolean
|
||||
ulb: boolean
|
||||
special: boolean
|
||||
updateUncap: (uncap: number) => void
|
||||
}
|
||||
|
||||
const UncapIndicator = (props: Props) => {
|
||||
let numStars
|
||||
const [uncap, setUncap] = useState(props.uncapLevel)
|
||||
|
||||
if (props.type === 'character') {
|
||||
if (props.flb) {
|
||||
numStars = 5
|
||||
const numStars = setNumStars()
|
||||
function setNumStars() {
|
||||
let numStars
|
||||
|
||||
if (props.type === 'character') {
|
||||
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
|
||||
} else {
|
||||
numStars = 4
|
||||
}
|
||||
}
|
||||
} else {
|
||||
numStars = 4
|
||||
}
|
||||
} else {
|
||||
if (props.ulb) {
|
||||
numStars = 5
|
||||
} else if (props.flb) {
|
||||
numStars = 4
|
||||
} else {
|
||||
numStars = 3
|
||||
if (props.ulb) {
|
||||
numStars = 5
|
||||
} else if (props.flb) {
|
||||
numStars = 4
|
||||
} else {
|
||||
numStars = 3
|
||||
}
|
||||
}
|
||||
|
||||
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 (
|
||||
<ul className="UncapIndicator">
|
||||
{
|
||||
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) {
|
||||
return <UncapStar uncap={true} key={`star_${i}`} />
|
||||
return flb(i)
|
||||
} else {
|
||||
return <UncapStar uncap={false} key={`star_${i}`} />
|
||||
return mlb(i)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,55 @@
|
|||
.UncapStar {
|
||||
color: #FFA15E;
|
||||
}
|
||||
background-repeat: no-repeat;
|
||||
background-size: 18px 18px;
|
||||
display: block;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
|
||||
.UncapStar.uncap {
|
||||
color: #65DAFF;
|
||||
&:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
&.empty,
|
||||
&.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'
|
||||
|
||||
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 classes = classnames({
|
||||
UncapStar: true,
|
||||
'uncap': props.uncap
|
||||
UncapStar: true,
|
||||
'empty': props.empty,
|
||||
'special': props.special,
|
||||
'mlb': !props.special,
|
||||
'flb': props.flb,
|
||||
'ulb': props.ulb
|
||||
|
||||
})
|
||||
|
||||
function clicked() {
|
||||
props.onClick(props.index, props.empty)
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -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 { AxiosResponse } from 'axios'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
import SearchModal from '~components/SearchModal'
|
||||
import WeaponUnit from '~components/WeaponUnit'
|
||||
import ExtraWeapons from '~components/ExtraWeapons'
|
||||
|
||||
import api from '~utils/api'
|
||||
import './index.scss'
|
||||
|
||||
// GridType
|
||||
|
|
@ -17,95 +23,235 @@ export enum GridType {
|
|||
|
||||
// Props
|
||||
interface Props {
|
||||
userId?: string
|
||||
partyId?: string
|
||||
mainhand?: Weapon | undefined
|
||||
grid: GridArray<Weapon>
|
||||
mainhand: GridWeapon | undefined
|
||||
weapons: GridArray<GridWeapon>
|
||||
extra: boolean
|
||||
editable: boolean
|
||||
exists: boolean
|
||||
found?: boolean
|
||||
onSelect: (type: GridType, weapon: Weapon, position: number) => void
|
||||
createParty: () => Promise<AxiosResponse<any, any>>
|
||||
pushHistory?: (path: string) => void
|
||||
}
|
||||
|
||||
const WeaponGrid = (props: Props) => {
|
||||
const { open, openModal, closeModal } = useModal()
|
||||
const [searchPosition, setSearchPosition] = useState(0)
|
||||
|
||||
// Constants
|
||||
const numWeapons: number = 9
|
||||
|
||||
const extraGrid = (
|
||||
<ExtraWeapons
|
||||
grid={props.grid}
|
||||
editable={props.editable}
|
||||
exists={false}
|
||||
offset={numWeapons}
|
||||
onClick={openSearchModal}
|
||||
/>
|
||||
)
|
||||
|
||||
function receiveWeapon(weapon: Weapon, position: number) {
|
||||
props.onSelect(GridType.Weapon, weapon, position)
|
||||
}
|
||||
|
||||
function sendData(object: Character | Weapon | Summon, position: number) {
|
||||
if (isWeapon(object)) {
|
||||
receiveWeapon(object, position)
|
||||
// Cookies
|
||||
const [cookies, _] = useCookies(['user'])
|
||||
const headers = (cookies.user != null) ? {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${cookies.user.access_token}`
|
||||
}
|
||||
}
|
||||
} : {}
|
||||
|
||||
function isWeapon(object: Character | Weapon | Summon): object is Weapon {
|
||||
return (object as Weapon).proficiency !== undefined
|
||||
}
|
||||
// Set up state for party
|
||||
const [partyId, setPartyId] = useState('')
|
||||
|
||||
// Set up states for Grid data
|
||||
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) {
|
||||
setSearchPosition(position)
|
||||
setItemPositionForSearch(position)
|
||||
openModal()
|
||||
}
|
||||
|
||||
function receiveWeaponFromSearch(object: Character | Weapon | Summon, position: number) {
|
||||
const weapon = object as Weapon
|
||||
|
||||
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
|
||||
gridWeapon={mainWeapon}
|
||||
editable={props.editable}
|
||||
key="grid_mainhand"
|
||||
position={-1}
|
||||
unitType={0}
|
||||
onClick={() => { openSearchModal(-1) }}
|
||||
updateUncap={initiateUncapUpdate}
|
||||
/>
|
||||
)
|
||||
|
||||
const weaponGridElement = (
|
||||
Array.from(Array(numWeapons)).map((x, i) => {
|
||||
return (
|
||||
<li key={`grid_unit_${i}`} >
|
||||
<WeaponUnit
|
||||
gridWeapon={weapons[i]}
|
||||
editable={props.editable}
|
||||
position={i}
|
||||
unitType={1}
|
||||
onClick={() => { openSearchModal(i) }}
|
||||
updateUncap={initiateUncapUpdate}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
const extraGridElement = (
|
||||
<ExtraWeapons
|
||||
grid={weapons}
|
||||
editable={props.editable}
|
||||
offset={numWeapons}
|
||||
onClick={openSearchModal}
|
||||
updateUncap={initiateUncapUpdate}
|
||||
/>
|
||||
)
|
||||
|
||||
return (
|
||||
<div id="weapon_grids">
|
||||
<div id="WeaponGrid">
|
||||
<WeaponUnit
|
||||
onClick={() => { openSearchModal(-1) }}
|
||||
editable={props.editable}
|
||||
key="grid_mainhand"
|
||||
position={-1}
|
||||
unitType={0}
|
||||
weapon={props.mainhand}
|
||||
/>
|
||||
|
||||
<ul id="grid_weapons">
|
||||
{
|
||||
Array.from(Array(numWeapons)).map((x, i) => {
|
||||
return (
|
||||
<li key={`grid_unit_${i}`} >
|
||||
<WeaponUnit
|
||||
onClick={() => { openSearchModal(i) }}
|
||||
editable={props.editable}
|
||||
position={i}
|
||||
unitType={1}
|
||||
weapon={props.grid[i]}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
{ mainhandElement }
|
||||
<ul id="grid_weapons">{ weaponGridElement }</ul>
|
||||
</div>
|
||||
|
||||
{ (() => {
|
||||
if(props.extra) {
|
||||
return extraGrid
|
||||
}
|
||||
})() }
|
||||
{ (() => { return (props.extra) ? extraGridElement : '' })() }
|
||||
|
||||
{open ? (
|
||||
<SearchModal
|
||||
grid={props.grid}
|
||||
grid={searchGrid}
|
||||
close={closeModal}
|
||||
send={sendData}
|
||||
fromPosition={searchPosition}
|
||||
send={receiveWeaponFromSearch}
|
||||
fromPosition={itemPositionForSearch}
|
||||
object="weapons"
|
||||
placeholderText="Search for a weapon..."
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 2px;
|
||||
overflow: hidden;
|
||||
transition: all 0.18s ease-in-out;
|
||||
}
|
||||
|
|
@ -19,7 +20,11 @@
|
|||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-shadow: rgba(0, 0, 0, 0.14) 0px 0px 14px;
|
||||
cursor: pointer;
|
||||
transform: scale(1.1, 1.1);
|
||||
transform: $scale-wide;
|
||||
}
|
||||
|
||||
.WeaponUnit.mainhand.editable .WeaponImage:hover {
|
||||
transform: $scale-tall;
|
||||
}
|
||||
|
||||
.WeaponUnit.filled h3 {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,18 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
|
||||
import classnames from 'classnames'
|
||||
|
||||
import UncapIndicator from '~components/UncapIndicator'
|
||||
|
||||
import PlusIcon from '~public/icons/plus.svg'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
interface Props {
|
||||
onClick: () => void
|
||||
weapon: Weapon | undefined
|
||||
gridWeapon: GridWeapon | undefined
|
||||
unitType: 0 | 1
|
||||
position: number
|
||||
editable: boolean
|
||||
unitType: 0 | 1
|
||||
onClick: () => void
|
||||
updateUncap: (id: string, position: number, uncap: number) => void
|
||||
}
|
||||
|
||||
const WeaponUnit = (props: Props) => {
|
||||
|
|
@ -24,10 +23,11 @@ const WeaponUnit = (props: Props) => {
|
|||
'mainhand': props.unitType == 0,
|
||||
'grid': props.unitType == 1,
|
||||
'editable': props.editable,
|
||||
'filled': (props.weapon !== undefined)
|
||||
'filled': (props.gridWeapon !== undefined)
|
||||
})
|
||||
|
||||
const weapon = props.weapon
|
||||
const gridWeapon = props.gridWeapon
|
||||
const weapon = gridWeapon?.weapon
|
||||
|
||||
useEffect(() => {
|
||||
generateImageUrl()
|
||||
|
|
@ -35,8 +35,8 @@ const WeaponUnit = (props: Props) => {
|
|||
|
||||
function generateImageUrl() {
|
||||
let imgSrc = ""
|
||||
if (props.weapon) {
|
||||
const weapon = props.weapon!
|
||||
if (props.gridWeapon) {
|
||||
const weapon = props.gridWeapon.weapon!
|
||||
|
||||
if (props.unitType == 0)
|
||||
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${weapon.granblue_id}.jpg`
|
||||
|
|
@ -47,6 +47,11 @@ const WeaponUnit = (props: Props) => {
|
|||
setImageUrl(imgSrc)
|
||||
}
|
||||
|
||||
function passUncapData(uncap: number) {
|
||||
if (props.gridWeapon)
|
||||
props.updateUncap(props.gridWeapon.id, props.position, uncap)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={classes}>
|
||||
|
|
@ -54,13 +59,17 @@ const WeaponUnit = (props: Props) => {
|
|||
<img alt={weapon?.name.en} className="grid_image" src={imageUrl} />
|
||||
{ (props.editable) ? <span className='icon'><PlusIcon /></span> : '' }
|
||||
</div>
|
||||
<UncapIndicator
|
||||
type="weapon"
|
||||
ulb={weapon?.uncap.ulb || false}
|
||||
flb={weapon?.uncap.flb || false}
|
||||
uncapLevel={3}
|
||||
/>
|
||||
<h3 className="WeaponName">{weapon?.name.en}</h3>
|
||||
{ (gridWeapon) ?
|
||||
<UncapIndicator
|
||||
type="weapon"
|
||||
ulb={gridWeapon.weapon.uncap.ulb || false}
|
||||
flb={gridWeapon.weapon.uncap.flb || false}
|
||||
uncapLevel={gridWeapon.uncap_level}
|
||||
updateUncap={passUncapData}
|
||||
special={false}
|
||||
/> : ''
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
50
package-lock.json
generated
|
|
@ -12,8 +12,10 @@
|
|||
"@radix-ui/react-label": "^0.1.4",
|
||||
"@radix-ui/react-switch": "^0.1.4",
|
||||
"@svgr/webpack": "^6.2.0",
|
||||
"@types/axios": "^0.14.0",
|
||||
"axios": "^0.25.0",
|
||||
"classnames": "^2.3.1",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"meyer-reset-scss": "^2.0.4",
|
||||
"next": "12.0.8",
|
||||
"react": "17.0.2",
|
||||
|
|
@ -23,6 +25,7 @@
|
|||
"sass": "^1.49.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash.debounce": "^4.0.6",
|
||||
"@types/node": "17.0.11",
|
||||
"@types/react": "17.0.38",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
|
|
@ -2980,6 +2983,15 @@
|
|||
"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": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz",
|
||||
|
|
@ -3000,6 +3012,21 @@
|
|||
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
|
||||
"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": {
|
||||
"version": "17.0.11",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz",
|
||||
|
|
@ -8757,6 +8792,21 @@
|
|||
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
|
||||
"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": {
|
||||
"version": "17.0.11",
|
||||
"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-switch": "^0.1.4",
|
||||
"@svgr/webpack": "^6.2.0",
|
||||
"@types/axios": "^0.14.0",
|
||||
"axios": "^0.25.0",
|
||||
"classnames": "^2.3.1",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"meyer-reset-scss": "^2.0.4",
|
||||
"next": "12.0.8",
|
||||
"react": "17.0.2",
|
||||
|
|
@ -28,6 +30,7 @@
|
|||
"sass": "^1.49.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash.debounce": "^4.0.6",
|
||||
"@types/node": "17.0.11",
|
||||
"@types/react": "17.0.38",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@ const PartyRoute: React.FC = () => {
|
|||
const [loading, setLoading] = useState(true)
|
||||
const [editable, setEditable] = useState(false)
|
||||
|
||||
const [characters, setCharacters] = useState<GridArray<Character>>({})
|
||||
const [weapons, setWeapons] = useState<GridArray<Weapon>>({})
|
||||
const [summons, setSummons] = useState<GridArray<Summon>>({})
|
||||
const [characters, setCharacters] = useState<GridArray<GridCharacter>>({})
|
||||
const [weapons, setWeapons] = useState<GridArray<GridWeapon>>({})
|
||||
const [summons, setSummons] = useState<GridArray<GridSummon>>({})
|
||||
|
||||
const [mainWeapon, setMainWeapon] = useState<Weapon>()
|
||||
const [mainSummon, setMainSummon] = useState<Summon>()
|
||||
const [friendSummon, setFriendSummon] = useState<Summon>()
|
||||
const [mainWeapon, setMainWeapon] = useState<GridWeapon>()
|
||||
const [mainSummon, setMainSummon] = useState<GridSummon>()
|
||||
const [friendSummon, setFriendSummon] = useState<GridSummon>()
|
||||
|
||||
const [partyId, setPartyId] = useState('')
|
||||
const [extra, setExtra] = useState<boolean>(false)
|
||||
|
|
@ -73,39 +73,39 @@ const PartyRoute: React.FC = () => {
|
|||
}
|
||||
|
||||
function populateCharacters(list: [GridCharacter]) {
|
||||
let characters: GridArray<Character> = {}
|
||||
let characters: GridArray<GridCharacter> = {}
|
||||
|
||||
list.forEach((object: GridCharacter) => {
|
||||
if (object.position != null)
|
||||
characters[object.position] = object.character
|
||||
characters[object.position] = object
|
||||
})
|
||||
|
||||
return characters
|
||||
}
|
||||
|
||||
function populateWeapons(list: [GridWeapon]) {
|
||||
let weapons: GridArray<Weapon> = {}
|
||||
let weapons: GridArray<GridWeapon> = {}
|
||||
|
||||
list.forEach((object: GridWeapon) => {
|
||||
if (object.mainhand)
|
||||
setMainWeapon(object.weapon)
|
||||
setMainWeapon(object)
|
||||
else if (!object.mainhand && object.position != null)
|
||||
weapons[object.position] = object.weapon
|
||||
weapons[object.position] = object
|
||||
})
|
||||
|
||||
return weapons
|
||||
}
|
||||
|
||||
function populateSummons(list: [GridSummon]) {
|
||||
let summons: GridArray<Summon> = {}
|
||||
let summons: GridArray<GridSummon> = {}
|
||||
|
||||
list.forEach((object: GridSummon) => {
|
||||
if (object.main)
|
||||
setMainSummon(object.summon)
|
||||
setMainSummon(object)
|
||||
else if (object.friend)
|
||||
setFriendSummon(object.summon)
|
||||
setFriendSummon(object)
|
||||
else if (!object.main && !object.friend && object.position != null)
|
||||
summons[object.position] = object.summon
|
||||
summons[object.position] = object
|
||||
})
|
||||
|
||||
return summons
|
||||
|
|
@ -129,7 +129,6 @@ const PartyRoute: React.FC = () => {
|
|||
weapons={weapons}
|
||||
summons={summons}
|
||||
editable={editable}
|
||||
exists={found}
|
||||
extra={extra}
|
||||
/>
|
||||
</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 |
|
|
@ -26,4 +26,8 @@ $bold: 600;
|
|||
$font-small: 12px;
|
||||
$font-regular: 14px;
|
||||
$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: {
|
||||
flb: boolean
|
||||
ulb: boolean
|
||||
}
|
||||
race: {
|
||||
race1: number
|
||||
|
|
@ -31,4 +32,5 @@ interface Character {
|
|||
proficiency2: number
|
||||
}
|
||||
position?: number
|
||||
special: boolean
|
||||
}
|
||||
3
types/GridCharacter.d.ts
vendored
|
|
@ -1,5 +1,6 @@
|
|||
interface GridCharacter {
|
||||
id: string
|
||||
position: number | null
|
||||
position: number
|
||||
character: Character
|
||||
uncap_level: number
|
||||
}
|
||||
3
types/GridSummon.d.ts
vendored
|
|
@ -2,6 +2,7 @@ interface GridSummon {
|
|||
id: string
|
||||
main: boolean
|
||||
friend: boolean
|
||||
position: number | null
|
||||
position: number
|
||||
summon: Summon
|
||||
uncap_level: number
|
||||
}
|
||||
3
types/GridWeapon.d.ts
vendored
|
|
@ -1,6 +1,7 @@
|
|||
interface GridWeapon {
|
||||
id: string
|
||||
mainhand: boolean
|
||||
position: number | null
|
||||
position: number
|
||||
weapon: Weapon
|
||||
uncap_level: number
|
||||
}
|
||||
|
|
@ -58,12 +58,23 @@ class Api {
|
|||
return axios.get(url)
|
||||
}
|
||||
|
||||
check(resource: string, value: string) {
|
||||
check(resource: 'username'|'email', value: string) {
|
||||
const resourceUrl = `${this.url}/check/${resource}`
|
||||
return axios.post(resourceUrl, {
|
||||
[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'})
|
||||
|
|
|
|||