Fix SearchModal and add WeaponResult
This commit is contained in:
parent
94cb909700
commit
a8672c8b72
5 changed files with 265 additions and 41 deletions
|
|
@ -1,10 +1,9 @@
|
|||
import React from 'react'
|
||||
import { v1 as uuidv1 } from 'uuid'
|
||||
|
||||
import Portal from '../../Portal'
|
||||
|
||||
import Modal from '../Modal/Modal'
|
||||
import Overlay from '../Overlay/Overlay'
|
||||
import WeaponResult from '../WeaponResult/WeaponResult'
|
||||
|
||||
import './SearchModal.css'
|
||||
|
||||
|
|
@ -16,8 +15,9 @@ interface Props {
|
|||
interface State {
|
||||
query: string,
|
||||
results: { [key: string]: any }
|
||||
isLoaded: boolean
|
||||
loading: boolean
|
||||
message: string
|
||||
totalResults: number
|
||||
}
|
||||
|
||||
class SearchModal extends React.Component<Props, State> {
|
||||
|
|
@ -28,62 +28,78 @@ class SearchModal extends React.Component<Props, State> {
|
|||
this.state = {
|
||||
query: '',
|
||||
results: {},
|
||||
isLoaded: false,
|
||||
message: ''
|
||||
}
|
||||
loading: false,
|
||||
message: '',
|
||||
totalResults: 0
|
||||
}
|
||||
}
|
||||
|
||||
fetchResults = (query) => {
|
||||
fetch(`http://127.0.0.1:3000/api/v1/search?query=${query}`)
|
||||
fetch(`http://grid-api.ngrok.io/api/v1/search?query=${query}`)
|
||||
.then(res => res.json())
|
||||
.then((result) => {
|
||||
// console.log("hello world!")
|
||||
console.log(result)
|
||||
// this.setState({
|
||||
// isLoaded: true,
|
||||
// results: result
|
||||
// })
|
||||
const totalResults = result.length
|
||||
this.setState({
|
||||
results: result,
|
||||
totalResults: totalResults,
|
||||
loading: false
|
||||
})
|
||||
}, (error) => {
|
||||
// this.setState({
|
||||
// isLoaded: true,
|
||||
// message: error
|
||||
// })
|
||||
this.setState({
|
||||
loading: false,
|
||||
message: error
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
inputChanged = (event) => {
|
||||
const query = this.searchQuery.value
|
||||
if (query.length > 2) {
|
||||
console.log(query)
|
||||
this.fetchResults(query)
|
||||
const query = event.target.value
|
||||
if (query.length) {
|
||||
this.setState({ query, loading: true, message: '' }, () => {
|
||||
this.fetchResults(query)
|
||||
})
|
||||
} else {
|
||||
this.setState({ query, results: {}, message: '' })
|
||||
}
|
||||
}
|
||||
|
||||
renderSearchResults = () => {
|
||||
const { results } = this.state
|
||||
|
||||
if (results.length) {
|
||||
return (
|
||||
<div id="results_container">
|
||||
{ results.map( result => {
|
||||
return <WeaponResult key={result.id} data={result} />
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// if (query) {
|
||||
// this.setState({ query, isLoaded: true, message: '' }, () => {
|
||||
// // this.fetchResults(query)
|
||||
// })
|
||||
// } else {
|
||||
// this.setState({ query, results: {}, message: '' })
|
||||
// }
|
||||
}
|
||||
|
||||
render() {
|
||||
const { query, isLoaded, message } = this.state
|
||||
const { query, loading } = this.state
|
||||
|
||||
return (
|
||||
<Portal key="search_portal">
|
||||
<Modal styleName="SearchModal" key="search_modal">
|
||||
<input
|
||||
className="Input"
|
||||
defaultValue={query}
|
||||
id="SearchInput"
|
||||
name="query"
|
||||
key="search_input_key"
|
||||
type="text"
|
||||
ref={el => this.searchQuery = el}
|
||||
onChange={this.inputChanged}
|
||||
placeholder={this.props.placeholderText}
|
||||
/>
|
||||
<div id="input_container">
|
||||
<label className="search_label" htmlFor="search_input">
|
||||
<input
|
||||
autoComplete="off"
|
||||
type="text"
|
||||
name="query"
|
||||
className="Input"
|
||||
id="search_input"
|
||||
value={query}
|
||||
placeholder={this.props.placeholderText}
|
||||
onChange={this.inputChanged}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{ this.renderSearchResults() }
|
||||
|
||||
</Modal>
|
||||
<Overlay onClick={this.props.close} />
|
||||
</Portal>
|
||||
|
|
|
|||
79
src/components/WeaponLabelIcon/WeaponLabelIcon.css
Normal file
79
src/components/WeaponLabelIcon/WeaponLabelIcon.css
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
.WeaponLabelIcon {
|
||||
display: inline-block;
|
||||
background-size: 60px 25px;
|
||||
height: 25px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
/* Elements */
|
||||
|
||||
.fire {
|
||||
background-image: url('../../images/labels/element/Label_Element_Fire.png')
|
||||
}
|
||||
|
||||
.water {
|
||||
background-image: url('../../images/labels/element/Label_Element_Water.png')
|
||||
}
|
||||
|
||||
.earth {
|
||||
background-image: url('../../images/labels/element/Label_Element_Earth.png')
|
||||
}
|
||||
|
||||
.wind {
|
||||
background-image: url('../../images/labels/element/Label_Element_Wind.png')
|
||||
}
|
||||
|
||||
.dark {
|
||||
background-image: url('../../images/labels/element/Label_Element_Dark.png')
|
||||
}
|
||||
|
||||
.light {
|
||||
background-image: url('../../images/labels/element/Label_Element_Light.png')
|
||||
}
|
||||
|
||||
.null {
|
||||
background-image: url('../../images/labels/element/Label_Element_Any.png')
|
||||
}
|
||||
|
||||
/* Proficiencies */
|
||||
|
||||
.sword {
|
||||
background-image: url('../../images/labels/proficiency/Label_Weapon_Sabre.png')
|
||||
}
|
||||
|
||||
.dagger {
|
||||
background-image: url('../../images/labels/proficiency/Label_Weapon_Dagger.png')
|
||||
}
|
||||
|
||||
.axe {
|
||||
background-image: url('../../images/labels/proficiency/Label_Weapon_Axe.png')
|
||||
}
|
||||
|
||||
.spear {
|
||||
background-image: url('../../images/labels/proficiency/Label_Weapon_Spear.png')
|
||||
}
|
||||
|
||||
.staff {
|
||||
background-image: url('../../images/labels/proficiency/Label_Weapon_Staff.png')
|
||||
}
|
||||
|
||||
.fist {
|
||||
background-image: url('../../images/labels/proficiency/Label_Weapon_Melee.png')
|
||||
}
|
||||
|
||||
.harp {
|
||||
background-image: url('../../images/labels/proficiency/Label_Weapon_Harp.png')
|
||||
}
|
||||
|
||||
.gun {
|
||||
background-image: url('../../images/labels/proficiency/Label_Weapon_Gun.png')
|
||||
}
|
||||
|
||||
.bow {
|
||||
background-image: url('../../images/labels/proficiency/Label_Weapon_Bow.png')
|
||||
}
|
||||
|
||||
.katana {
|
||||
background-image: url('../../images/labels/proficiency/Label_Weapon_Katana.png')
|
||||
}
|
||||
|
||||
16
src/components/WeaponLabelIcon/WeaponLabelIcon.tsx
Normal file
16
src/components/WeaponLabelIcon/WeaponLabelIcon.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import React from 'react'
|
||||
import './WeaponLabelIcon.css'
|
||||
|
||||
interface Props {
|
||||
labelType: string
|
||||
}
|
||||
|
||||
class WeaponLabelIcon extends React.Component<Props> {
|
||||
render() {
|
||||
return (
|
||||
<i className={`WeaponLabelIcon ${this.props.labelType}`} />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default WeaponLabelIcon
|
||||
48
src/components/WeaponResult/WeaponResult.css
Normal file
48
src/components/WeaponResult/WeaponResult.css
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
.WeaponResult {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
font-family: -apple-system, "Helvetica Neue", "Lucida Grande";
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.WeaponResult img {
|
||||
background: #e9e9e9;
|
||||
border-radius: 6px;
|
||||
display: inline-block;
|
||||
height: 72px;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.WeaponResult h5 {
|
||||
color: #555;
|
||||
display: inline-block;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
margin: 2px 4px 4px 0;
|
||||
}
|
||||
|
||||
.WeaponResult .WeaponLabelIcon {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.WeaponResult .stars {
|
||||
display: inline-block;
|
||||
color: #FFA15E;
|
||||
font-size: 21px;
|
||||
}
|
||||
|
||||
.WeaponResult .stars > span {
|
||||
color: #65DAFF;
|
||||
}
|
||||
|
||||
.WeaponResult:hover {
|
||||
background: #e9e9e9;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.WeaponResult:hover .image_placeholder {
|
||||
background: #dadada;
|
||||
}
|
||||
65
src/components/WeaponResult/WeaponResult.tsx
Normal file
65
src/components/WeaponResult/WeaponResult.tsx
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import React from 'react'
|
||||
import './WeaponResult.css'
|
||||
|
||||
import '../WeaponLabelIcon/WeaponLabelIcon'
|
||||
import WeaponLabelIcon from '../WeaponLabelIcon/WeaponLabelIcon'
|
||||
|
||||
import gridImages from '../../images/grid/*.jpg'
|
||||
|
||||
interface Weapon {
|
||||
id: string
|
||||
granblue_id: number
|
||||
element: number
|
||||
proficiency: number
|
||||
max_level: number
|
||||
max_skill_level: number
|
||||
name: {
|
||||
en: string
|
||||
jp: string
|
||||
}
|
||||
hp: {
|
||||
min_hp: number
|
||||
max_hp: number
|
||||
max_hp_flb: number
|
||||
max_hp_ulb: number
|
||||
}
|
||||
atk: {
|
||||
min_atk: number
|
||||
max_atk: number
|
||||
max_atk_flb: number
|
||||
max_atk_ulb: number
|
||||
}
|
||||
uncap: {
|
||||
flb: boolean
|
||||
ulb: boolean
|
||||
}
|
||||
}
|
||||
|
||||
interface Props {
|
||||
data: Weapon
|
||||
}
|
||||
|
||||
const Element = ['null', 'wind', 'fire', 'water', 'earth', 'dark', 'light']
|
||||
const Proficiency = ['none', 'sword', 'dagger', 'axe', 'spear', 'bow', 'staff', 'fist', 'harp', 'gun', 'katana']
|
||||
|
||||
|
||||
class WeaponResult extends React.Component<Props> {
|
||||
render() {
|
||||
const weapon = this.props.data
|
||||
return (
|
||||
<div className="WeaponResult">
|
||||
<img alt={weapon.name.en} src={gridImages[weapon.granblue_id]} />
|
||||
<div>
|
||||
<div>
|
||||
<h5>{weapon.name.en}</h5>
|
||||
<div className="stars">⭑⭑⭑{(weapon.uncap.flb) ? <span>⭑</span> : ''}{(weapon.uncap.ulb) ? <span>⭑</span> : ''}</div>
|
||||
</div>
|
||||
<WeaponLabelIcon labelType={Element[weapon.element]} />
|
||||
<WeaponLabelIcon labelType={Proficiency[weapon.proficiency]} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default WeaponResult
|
||||
Loading…
Reference in a new issue