Migrate to Next.js

This commit is contained in:
Justin Edmund 2022-01-24 21:54:50 -08:00
parent 6c585b4d22
commit 728803d9c5
129 changed files with 3847 additions and 17861 deletions

View file

@ -1,4 +0,0 @@
{
"plugins": ["@babel/plugin-transform-runtime"],
"presets": ["@babel/preset-env", "@babel/preset-react"]
}

3
.eslintrc.json Normal file
View file

@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}

6
.gitignore vendored
View file

@ -47,9 +47,9 @@ dist/
# Source images # Source images
# Instructions will be provided to download these from the game # Instructions will be provided to download these from the game
src/images/weapon* public/images/weapon*
src/images/summon* public/images/summon*
src/images/chara* public/images/chara*
# Typescript v1 declaration files # Typescript v1 declaration files
typings/ typings/

View file

@ -1,10 +0,0 @@
const path = require('path');
const cwd = process.cwd();
module.exports = {
data: '@import "globals";',
'includePaths': [
'node_modules',
'assets/scss'
]
}

34
README.md Normal file
View file

@ -0,0 +1,34 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.

View file

@ -5,7 +5,7 @@ import api from '~utils/api'
import Modal from '~components/Modal' import Modal from '~components/Modal'
import Overlay from '~components/Overlay' import Overlay from '~components/Overlay'
import './index.css' import './index.module.css'
interface Props { interface Props {
close: () => void close: () => void

29
components/App/index.tsx Normal file
View file

@ -0,0 +1,29 @@
import React from 'react'
import { Route, Routes, useNavigate } from 'react-router-dom'
import Header from '~components/Header'
import NewRoute from '~routes/NewRoute'
import PartyRoute from '~routes/PartyRoute'
import PartiesRoute from '~routes/PartiesRoute'
import ProfileRoute from '~routes/ProfileRoute'
const App = () => {
const navigate = useNavigate()
const route = (pathname: string) => navigate(pathname)
return (
<div>
<Header navigate={route} />
<Routes>
<Route path='/' element={<NewRoute />} />
<Route path='/parties/' element={<PartiesRoute />} />
<Route path='/p/:hash' element={<PartyRoute />} />
<Route path='/:username' element={<ProfileRoute />} />
</Routes>
</div>
)
}
export default App

View file

@ -1,13 +1,10 @@
button {
border: none;
font-weight: $medium;
}
.Button { .Button {
align-items: center; align-items: center;
border: none;
border-radius: 6px; border-radius: 6px;
display: inline-flex; display: inline-flex;
font-size: 1.4rem; font-size: 1.4rem;
font-weight: $medium;
gap: 6px; gap: 6px;
padding: 8px 12px; padding: 8px 12px;
@ -86,10 +83,4 @@ button {
.text { .text {
color: inherit; color: inherit;
} }
}
@include media('>small', '<=medium') {
.Button {
font-size: 1.6rem;
}
} }

View file

@ -1,12 +1,9 @@
import React from 'react' import React from 'react'
import Image from 'next/image'
import classNames from 'classnames' import classNames from 'classnames'
import './index.scss' import './index.scss'
import New from '../../../assets/new'
import Menu from '../../../assets/menu'
import Link from '../../../assets/link'
interface Props { interface Props {
color: string color: string
disabled: boolean disabled: boolean
@ -36,11 +33,17 @@ class Button extends React.Component<Props, State> {
render() { render() {
let icon let icon
if (this.props.type === 'new') { if (this.props.type === 'new') {
icon = <span className='icon'><New /></span> icon = <span className='icon'>
<img src="/icons/new.svg" />
</span>
} else if (this.props.type === 'menu') { } else if (this.props.type === 'menu') {
icon = <span className='icon'><Menu /></span> icon = <span className='icon'>
<img src="/icons/menu.svg" />
</span>
} else if (this.props.type === 'link') { } else if (this.props.type === 'link') {
icon = <span className='icon'><Link /></span> icon = <span className='icon'>
<img src="/icons/link.svg" />
</span>
} }
const classes = classNames({ const classes = classNames({

View file

@ -1,8 +1,7 @@
import React from 'react' import React from 'react'
import Image from 'next/image'
import WeaponLabelIcon from '~components/WeaponLabelIcon' import WeaponLabelIcon from '~components/WeaponLabelIcon'
import images from '../../images/chara-grid/*.jpg'
import './index.scss' import './index.scss'
interface Props { interface Props {
@ -14,18 +13,11 @@ const Element = ['null', 'wind', 'fire', 'water', 'earth', 'dark', 'light']
class CharacterResult extends React.Component<Props> { class CharacterResult extends React.Component<Props> {
render() { render() {
let imgSrc
const character = this.props.data const character = this.props.data
if (process.env.NODE_ENV === 'development') {
imgSrc = images[character.granblue_id]
} else if (process.env.NODE_ENV === 'production') {
imgSrc = `${process.env.REACT_APP_SIERO_IMG_URL}/chara-grid/${character.granblue_id}.jpg`
}
return ( return (
<li className="CharacterResult" onClick={this.props.onClick}> <li className="CharacterResult" onClick={this.props.onClick}>
<img alt={character.name.en} src={imgSrc} /> <img alt={character.name.en} src={`/images/chara-grid/${character.granblue_id}.jpg`} />
<div> <div>
<div> <div>
<h5>{character.name.en}</h5> <h5>{character.name.en}</h5>

View file

@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import Image from 'next/image'
import classnames from 'classnames' import classnames from 'classnames'
import { useModal as useModal } from '~utils/useModal' import { useModal as useModal } from '~utils/useModal'
@ -7,9 +8,6 @@ import UncapIndicator from '~components/UncapIndicator'
import './index.scss' import './index.scss'
import images from '../../images/chara-main/*.jpg'
import Plus from '../../../assets/plus.svg'
interface Props { interface Props {
onReceiveData: (character: Character, position: number) => void onReceiveData: (character: Character, position: number) => void
character: Character | undefined character: Character | undefined
@ -35,17 +33,13 @@ const CharacterUnit = (props: Props) => {
generateImageUrl() generateImageUrl()
}) })
function generateImageUrl() { function generateImageUrl() {
let imgSrc let imgSrc = ""
if (props.character) { if (props.character) {
const character = props.character! const character = props.character!
imgSrc = `/images/chara-main/${character.granblue_id}.jpg`
// Generate the correct source for the weapon
if (process.env.NODE_ENV === 'development') {
imgSrc = images[character.granblue_id]
} else if (process.env.NODE_ENV === 'production') {
imgSrc = `${process.env.REACT_APP_SIERO_IMG_URL}/chara-main/${character.granblue_id}.jpg`
}
} }
setImageUrl(imgSrc) setImageUrl(imgSrc)
@ -66,13 +60,8 @@ const CharacterUnit = (props: Props) => {
<div> <div>
<div className={classes} onClick={openModalIfEditable}> <div className={classes} onClick={openModalIfEditable}>
<div className="CharacterImage"> <div className="CharacterImage">
{ <img alt="ALT TEXT GOES HERE" className="grid_image" src={imageUrl} />
(imageUrl != '') { (props.editable) ? <span className='icon'><img src="/icons/plus.svg" /></span> : '' }
? <img className="grid_image" src={imageUrl} />
: <img className="grid_image" />
}
{ (props.editable) ? <span className='icon'><Plus /></span> : '' }
</div> </div>
<UncapIndicator <UncapIndicator
type="character" type="character"

View file

@ -26,7 +26,7 @@
padding: 4px 16px; padding: 4px 16px;
} }
::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */ // ::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
color: #a9a9a9 !important; // color: #a9a9a9 !important;
opacity: 1; /* Firefox */ // opacity: 1; /* Firefox */
} // }

View file

@ -1,5 +1,5 @@
import React from 'react' import React from 'react'
import './index.css' import './index.scss'
interface Props { interface Props {
fieldName: string fieldName: string

View file

@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import Image from 'next/image'
import './index.css' import './index.scss'
import mainhandImages from '../../images/weapon-main/*.jpg' import mainhandImages from '../../images/weapon-main/*.jpg'
import gridImages from '../../images/weapon-grid/*.jpg' import gridImages from '../../images/weapon-grid/*.jpg'
@ -39,23 +40,11 @@ const GridRep = (props: Props) => {
} }
function generateMainhandImage() { function generateMainhandImage() {
return (mainhand) return <img alt="ALT TEXT GOES HERE" src={`/images/weapon-main/${mainhand?.granblue_id}.jpg`} />
? <img src={
process.env.NODE_ENV === 'development'
? mainhandImages[mainhand?.granblue_id || 0]
: `${process.env.REACT_APP_SIERO_IMG_URL}/weapon-main/${mainhand?.granblue_id}.jpg`
} />
: <img />
} }
function generateGridImage(position: number) { function generateGridImage(position: number) {
return (weapons[position]) return <img alt="ALT TEXT GOES HERE" src={`/images/weapon-grid/${weapons[position]?.granblue_id}.jpg`} />
? <img src={
process.env.NODE_ENV === 'development'
? gridImages[weapons[position]?.granblue_id || 0]
: `${process.env.REACT_APP_SIERO_IMG_URL}/weapon-grid/${weapons[position]?.granblue_id}.jpg`
} />
: <img />
} }
return ( return (

View file

@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import './index.css' import './index.scss'
interface Props {} interface Props {}

View file

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { useHistory, useLocation } from 'react-router-dom' import { useNavigate, useLocation } from 'react-router-dom'
import { useCookies } from 'react-cookie' import { useCookies } from 'react-cookie'
import Button from '~components/Button' import Button from '~components/Button'
@ -15,7 +15,7 @@ const Header = (props: Props) => {
const [username, setUsername] = useState(undefined) const [username, setUsername] = useState(undefined)
const [cookies, setCookie, removeCookie] = useCookies(['user']) const [cookies, setCookie, removeCookie] = useCookies(['user'])
let history = useHistory() let navigate = useNavigate()
let location = useLocation() let location = useLocation()
const route = (pathname: string) => props.navigate(pathname) const route = (pathname: string) => props.navigate(pathname)
@ -39,13 +39,13 @@ const Header = (props: Props) => {
} }
function newParty() { function newParty() {
props.navigate('/') navigate('/')
} }
function logout() { function logout() {
removeCookie('user') removeCookie('user')
window.history.replaceState(null, `Grid Tool`, `/`) window.history.replaceState(null, `Grid Tool`, `/`)
history.go(0) navigate(0)
} }
return ( return (

View file

@ -8,9 +8,9 @@ import Fieldset from '~components/Fieldset'
import Modal from '~components/Modal' import Modal from '~components/Modal'
import Overlay from '~components/Overlay' import Overlay from '~components/Overlay'
import './index.css' import './index.scss'
import New from '../../../assets/new' // import New from '../../../assets/new'
interface Props { interface Props {
cookies: Cookies cookies: Cookies
@ -111,7 +111,8 @@ const LoginModal = (props: Props) => {
<Modal styleName="LoginForm"> <Modal styleName="LoginForm">
<div id="ModalTop"> <div id="ModalTop">
<h1>Log in</h1> <h1>Log in</h1>
<i className='close' onClick={props.close}><New /></i> {/* <i className='close' onClick={props.close}><New /></i> */}
<i className='close' onClick={props.close}></i>
</div> </div>
<form className="form" onSubmit={submit}> <form className="form" onSubmit={submit}>
<div id="fields"> <div id="fields">

View file

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
import classnames from 'classnames' import classnames from 'classnames'
import './index.css' import './index.scss'
interface Props { interface Props {
styleName?: string styleName?: string

View file

@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import './index.css' import './index.scss'
interface Props { interface Props {
onClick: OnClickEvent onClick: OnClickEvent

View file

@ -11,14 +11,15 @@ import SummonGrid from '~components/SummonGrid'
import CharacterGrid from '~components/CharacterGrid' import CharacterGrid from '~components/CharacterGrid'
// GridType // GridType
export enum GridType { enum GridType {
Class, Class,
Character, Character,
Weapon, Weapon,
Summon Summon
} }
export { GridType }
import './index.css' import './index.scss'
interface Props { interface Props {
partyId?: string partyId?: string

View file

@ -8,7 +8,7 @@ import CharacterResult from '~components/CharacterResult'
import WeaponResult from '~components/WeaponResult' import WeaponResult from '~components/WeaponResult'
import SummonResult from '~components/SummonResult' import SummonResult from '~components/SummonResult'
import './index.css' import './index.scss'
interface Props { interface Props {
close: () => void close: () => void

View file

@ -33,11 +33,4 @@
background: #fff; background: #fff;
} }
} }
}
@include media('>small', '<=medium') {
.Segment {
flex-grow: 1;
font-size: 1.6rem;
}
} }

View file

@ -13,14 +13,4 @@
overflow: hidden; overflow: hidden;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
z-index: 1; z-index: 1;
}
@include media('>small', '<=medium') {
.SegmentedControlWrapper {
justify-content: stretch;
}
.SegmentedControl {
width: 100%;
}
} }

View file

@ -8,9 +8,9 @@ import Fieldset from '~components/Fieldset'
import Modal from '~components/Modal' import Modal from '~components/Modal'
import Overlay from '~components/Overlay' import Overlay from '~components/Overlay'
import './index.css' import './index.scss'
import New from '../../../assets/new' // import New from '../../../assets/new'
interface Props { interface Props {
cookies: Cookies cookies: Cookies

View file

@ -1,9 +1,8 @@
import React from 'react' import React from 'react'
import Image from 'next/image'
import WeaponLabelIcon from '~components/WeaponLabelIcon' import WeaponLabelIcon from '~components/WeaponLabelIcon'
import gridImages from '../../images/summon-grid/*.jpg' import './index.scss'
import './index.css'
interface Props { interface Props {
data: Summon data: Summon
@ -14,18 +13,11 @@ const Element = ['null', 'wind', 'fire', 'water', 'earth', 'dark', 'light']
class SummonResult extends React.Component<Props> { class SummonResult extends React.Component<Props> {
render() { render() {
let imgSrc
const summon = this.props.data const summon = this.props.data
if (process.env.NODE_ENV === 'development') {
imgSrc = gridImages[summon.granblue_id]
} else if (process.env.NODE_ENV === 'production') {
imgSrc = `${process.env.REACT_APP_SIERO_IMG_URL}/summon-grid/${summon.granblue_id}.jpg`
}
return ( return (
<li className="SummonResult" onClick={this.props.onClick}> <li className="SummonResult" onClick={this.props.onClick}>
<img alt={summon.name.en} src={imgSrc} /> <img alt={summon.name.en} src={`/images/summon-grid/${summon.granblue_id}.jpg`} />
<div> <div>
<div> <div>
<h5>{summon.name.en}</h5> <h5>{summon.name.en}</h5>

View file

@ -1,14 +1,12 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import Image from 'next/image'
import classnames from 'classnames' import classnames from 'classnames'
import { useModal as useModal } from '~utils/useModal' import { useModal as useModal } from '~utils/useModal'
import SearchModal from '~components/SearchModal' import SearchModal from '~components/SearchModal'
import UncapIndicator from '~components/UncapIndicator' import UncapIndicator from '~components/UncapIndicator'
import mainImages from '../../images/summon-main/*.jpg'
import gridImages from '../../images/summon-grid/*.jpg'
import Plus from '../../../assets/plus.svg'
import './index.scss' import './index.scss'
interface Props { interface Props {
@ -41,22 +39,15 @@ const SummonUnit = (props: Props) => {
}) })
function generateImageUrl() { function generateImageUrl() {
let imgSrc let imgSrc = ""
if (props.summon) { if (props.summon) {
const summon = props.summon! const summon = props.summon!
// Generate the correct source for the weapon // Generate the correct source for the summon
if (process.env.NODE_ENV === 'development') { if (props.unitType == 0 || props.unitType == 2)
if (props.unitType == 0 || props.unitType == 2) imgSrc = `/images/summon-main/${summon.granblue_id}.jpg`
imgSrc = mainImages[summon.granblue_id] else
else imgSrc = `/images/summon-grid/${summon.granblue_id}.jpg`
imgSrc = gridImages[summon.granblue_id]
} else if (process.env.NODE_ENV === 'production') {
if (props.unitType == 0 || props.unitType == 2)
imgSrc = `${process.env.REACT_APP_SIERO_IMG_URL}/summon-main/${summon.granblue_id}.jpg`
else
imgSrc = `${process.env.REACT_APP_SIERO_IMG_URL}/summon-grid/${summon.granblue_id}.jpg`
}
} }
setImageUrl(imgSrc) setImageUrl(imgSrc)
@ -77,13 +68,8 @@ const SummonUnit = (props: Props) => {
<div> <div>
<div className={classes} onClick={openModalIfEditable}> <div className={classes} onClick={openModalIfEditable}>
<div className="SummonImage"> <div className="SummonImage">
{ <img alt="ALT TEXT GOES HERE" className="grid_image" src={imageUrl} />
(imageUrl != '') { (props.editable) ? <span className='icon'><img src="/icons/plus.svg" /></span> : '' }
? <img className="grid_image" src={imageUrl} />
: <img className="grid_image" />
}
{ (props.editable) ? <span className='icon'><Plus /></span> : '' }
</div> </div>
<UncapIndicator <UncapIndicator
type="summon" type="summon"

View file

@ -2,7 +2,7 @@ import React from 'react'
import classnames from 'classnames' import classnames from 'classnames'
import UncapStar from '~components/UncapStar' import UncapStar from '~components/UncapStar'
import './index.css' import './index.scss'
interface Props { interface Props {

View file

@ -1,9 +1,8 @@
import React from 'react' import React from 'react'
import Image from 'next/image'
import classnames from 'classnames' import classnames from 'classnames'
import './index.css' import './index.scss'
import Star from '../../../assets/star'
interface Props { interface Props {
uncap: boolean uncap: boolean
@ -16,7 +15,7 @@ const UncapStar = (props: Props) => {
}) })
return ( return (
<li className={classes}><Star /></li> <li className={classes}><img src="/icons/star.svg" /></li>
) )
} }

View 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')
}

View file

@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import './index.css' import './index.scss'
interface Props { interface Props {
labelType: string labelType: string

View file

@ -1,9 +1,8 @@
import React from 'react' import React from 'react'
import Image from 'next/image'
import WeaponLabelIcon from '~components/WeaponLabelIcon' import WeaponLabelIcon from '~components/WeaponLabelIcon'
import gridImages from '../../images/weapon-grid/*.jpg' import './index.scss'
import './index.css'
interface Props { interface Props {
data: Weapon data: Weapon
@ -16,18 +15,11 @@ const Series = ['seraphic', 'grand', 'opus', 'draconic', 'revenant', 'primal', '
class WeaponResult extends React.Component<Props> { class WeaponResult extends React.Component<Props> {
render() { render() {
let imgSrc
const weapon = this.props.data const weapon = this.props.data
if (process.env.NODE_ENV === 'development') {
imgSrc = gridImages[weapon.granblue_id]
} else if (process.env.NODE_ENV === 'production') {
imgSrc = `${process.env.REACT_APP_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}.jpg`
}
return ( return (
<li className="WeaponResult" onClick={this.props.onClick}> <li className="WeaponResult" onClick={this.props.onClick}>
<img alt={weapon.name.en} src={imgSrc} /> <img alt={weapon.name.en} src={`/images/weapon-grid/${weapon.granblue_id}.jpg`} />
<div> <div>
<div> <div>
<h5>{weapon.name.en}</h5> <h5>{weapon.name.en}</h5>

View file

@ -1,14 +1,12 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import Image from 'next/image'
import classnames from 'classnames' import classnames from 'classnames'
import { useModal as useModal } from '~utils/useModal' import { useModal as useModal } from '~utils/useModal'
import SearchModal from '~components/SearchModal' import SearchModal from '~components/SearchModal'
import UncapIndicator from '~components/UncapIndicator' import UncapIndicator from '~components/UncapIndicator'
import mainImages from '../../images/weapon-main/*.jpg'
import gridImages from '../../images/weapon-grid/*.jpg'
import Plus from '../../../assets/plus.svg'
import './index.scss' import './index.scss'
interface Props { interface Props {
@ -41,22 +39,14 @@ const WeaponUnit = (props: Props) => {
}) })
function generateImageUrl() { function generateImageUrl() {
let imgSrc let imgSrc = ""
if (props.weapon) { if (props.weapon) {
const weapon = props.weapon! const weapon = props.weapon!
// Generate the correct source for the weapon if (props.unitType == 0)
if (process.env.NODE_ENV === 'development') { imgSrc = `/images/weapon-main/${weapon.granblue_id}.jpg`
if (props.unitType == 0) else
imgSrc = mainImages[weapon.granblue_id] imgSrc = `/images/weapon-grid/${weapon.granblue_id}.jpg`
else
imgSrc = gridImages[weapon.granblue_id]
} else if (process.env.NODE_ENV === 'production') {
if (props.unitType == 0)
imgSrc = `${process.env.REACT_APP_SIERO_IMG_URL}/weapon-main/${weapon.granblue_id}.jpg`
else
imgSrc = `${process.env.REACT_APP_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}.jpg`
}
} }
setImageUrl(imgSrc) setImageUrl(imgSrc)
@ -76,13 +66,8 @@ const WeaponUnit = (props: Props) => {
<div> <div>
<div className={classes} onClick={openModalIfEditable}> <div className={classes} onClick={openModalIfEditable}>
<div className="WeaponImage"> <div className="WeaponImage">
{ <img alt="ALT TEXT GOES HERE" className="grid_image" src={imageUrl} />
(imageUrl != '') { (props.editable) ? <span className='icon'><img src="/icons/plus.svg" /></span> : '' }
? <img className="grid_image" src={imageUrl} />
: <img className="grid_image" />
}
{ (props.editable) ? <span className='icon'><Plus /></span> : '' }
</div> </div>
<UncapIndicator <UncapIndicator
type="weapon" type="weapon"

View file

@ -1,17 +0,0 @@
const express = require('express');
const path = require('path');
const app = express();
// Serve the static files from the React app
app.use(express.static(path.join(__dirname, 'dist')));
// Handles any requests that don't match the ones above
app.get('*', (req, res) =>{
res.sendFile(path.join(__dirname+'/dist/index.html'));
});
const port = process.env.PORT || 3000;
app.listen(port);
console.log('App is listening on port ' + port);

View file

@ -1,5 +0,0 @@
{
"compilerOptions": {
"baseUrl": "src"
}
}

17
next.config.js Normal file
View file

@ -0,0 +1,17 @@
/** @type {import('next').NextConfig} */
const path = require('path')
module.exports = {reactStrictMode: true,
sassOptions: {
prependData: '@import "variables";',
includePaths: [path.join(__dirname, 'styles')],
},
webpack(config) {
config.module.rules[2].oneOf.forEach((one) => {
if (!`${one.issuer?.and}`.includes('_app')) return;
one.issuer.and = [path.resolve(__dirname)];
});
return config;
},
};

20682
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,53 +1,29 @@
{ {
"name": "hensei-web", "name": "grid-web",
"version": "1.0.0", "private": true,
"author": "Justin Edmund (@jedmund)", "scripts": {
"main": "./src/index.html", "dev": "next dev -p 1234",
"browserslist": "last 2 versions", "build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": { "dependencies": {
"@babel/core": "^7.16.12",
"@babel/plugin-transform-runtime": "^7.16.10",
"@svgr/parcel-plugin-svgr": "^5.5.0",
"@types/axios": "^0.14.0",
"@types/classnames": "^2.3.0",
"@types/react-router": "^5.1.18",
"@types/react-router-dom": "^5.3.3",
"autoprefixer": "^10.4.2",
"axios": "^0.25.0", "axios": "^0.25.0",
"classnames": "^2.3.1", "classnames": "^2.3.1",
"components": "^0.1.0",
"dotenv": "^14.3.0",
"express": "^4.17.2",
"i18next": "^21.6.7",
"i18next-browser-languagedetector": "^6.1.2",
"i18next-xhr-backend": "^3.2.2",
"include-media": "^1.4.10",
"meyer-reset-scss": "^2.0.4", "meyer-reset-scss": "^2.0.4",
"next": "^12.0.8", "next": "12.0.8",
"parcel-bundler": "^1.12.4", "react": "17.0.2",
"postcss-modules": "^4.3.0",
"postcss-normalize": "^10.0.1",
"react": "^17.0.2",
"react-cookie": "^4.1.1", "react-cookie": "^4.1.1",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-i18next": "^11.15.3", "react-i18next": "^11.15.3",
"react-router-dom": "^6.2.1", "react-router-dom": "^6.2.1",
"sass": "^1.49.0", "sass": "^1.49.0"
"typescript": "^4.5.5"
},
"scripts": {
"dev": "next dev -p 1234",
"build": "next build",
"start": "next start"
},
"compilerOptions": {
"jsx": "react",
"next": "latest",
"react": "latest",
"react-dom": "latest"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^17.0.11", "@types/node": "17.0.11",
"node-sass-package-importer": "^5.3.2" "@types/react": "17.0.38",
"eslint": "8.7.0",
"eslint-config-next": "12.0.8",
"typescript": "4.5.5"
} }
} }

9
pages/_app.tsx Normal file
View file

@ -0,0 +1,9 @@
import '../styles/globals.scss'
import type { AppProps } from 'next/app'
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
export default MyApp

13
pages/api/hello.ts Normal file
View file

@ -0,0 +1,13 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'
type Data = {
name: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
res.status(200).json({ name: 'John Doe' })
}

24
pages/index.tsx Normal file
View file

@ -0,0 +1,24 @@
import type { NextPage } from 'next'
import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
import { CookiesProvider } from 'react-cookie'
import { BrowserRouter } from 'react-router-dom'
import App from '~/components/App'
const Home: NextPage = () => {
if (typeof window === "undefined")
return null
return (
<BrowserRouter>
<CookiesProvider>
<App />
</CookiesProvider>
</BrowserRouter>
)
}
export default Home

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

3
public/icons/menu.svg Normal file
View file

@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 1C0 0.447715 0.447715 0 1 0H11C11.5523 0 12 0.447715 12 1C12 1.55228 11.5523 2 11 2H1C0.447715 2 0 1.55228 0 1ZM0 6C0 5.44772 0.447715 5 1 5H11C11.5523 5 12 5.44772 12 6C12 6.55228 11.5523 7 11 7H1C0.447715 7 0 6.55228 0 6ZM1 10C0.447715 10 0 10.4477 0 11C0 11.5523 0.447715 12 1 12H11C11.5523 12 12 11.5523 12 11C12 10.4477 11.5523 10 11 10H1Z" />
</svg>

After

Width:  |  Height:  |  Size: 496 B

View file

Before

Width:  |  Height:  |  Size: 414 B

After

Width:  |  Height:  |  Size: 414 B

View file

Before

Width:  |  Height:  |  Size: 700 B

After

Width:  |  Height:  |  Size: 700 B

View file

Before

Width:  |  Height:  |  Size: 754 B

After

Width:  |  Height:  |  Size: 754 B

View file

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View file

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View file

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View file

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View file

Before

Width:  |  Height:  |  Size: 6 KiB

After

Width:  |  Height:  |  Size: 6 KiB

View file

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View file

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View file

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View file

@ -1,3 +0,0 @@
<svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 1C0 0.447715 0.447715 0 1 0H11C11.5523 0 12 0.447715 12 1C12 1.55228 11.5523 2 11 2H1C0.447715 2 0 1.55228 0 1ZM0 6C0 5.44772 0.447715 5 1 5H11C11.5523 5 12 5.44772 12 6C12 6.55228 11.5523 7 11 7H1C0.447715 7 0 6.55228 0 6ZM1 10C0.447715 10 0 10.4477 0 11C0 11.5523 0.447715 12 1 12H11C11.5523 12 12 11.5523 12 11C12 10.4477 11.5523 10 11 10H1Z" />
</svg>

Before

Width:  |  Height:  |  Size: 492 B

Some files were not shown because too many files have changed in this diff Show more