Add modal for network errors
This commit is contained in:
parent
6da5a4f320
commit
ab928f4429
6 changed files with 104 additions and 17 deletions
|
|
@ -23,7 +23,11 @@ const Alert = (props: Props) => {
|
|||
<AlertDialog.Overlay className="Overlay" onClick={props.cancelAction} />
|
||||
<div className="AlertWrapper">
|
||||
<AlertDialog.Content className="Alert">
|
||||
{props.title ? <AlertDialog.Title>Error</AlertDialog.Title> : ''}
|
||||
{props.title ? (
|
||||
<AlertDialog.Title>{props.title}</AlertDialog.Title>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<AlertDialog.Description className="description">
|
||||
{props.message}
|
||||
</AlertDialog.Description>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@
|
|||
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { getCookie } from 'cookies-next'
|
||||
import { useSnapshot } from 'valtio'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
||||
import { AxiosResponse } from 'axios'
|
||||
import { AxiosError, AxiosResponse } from 'axios'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
import Alert from '~components/Alert'
|
||||
|
|
@ -31,12 +32,19 @@ const CharacterGrid = (props: Props) => {
|
|||
// Constants
|
||||
const numCharacters: number = 5
|
||||
|
||||
// Localization
|
||||
const { t } = useTranslation('common')
|
||||
|
||||
// Cookies
|
||||
const cookie = getCookie('account')
|
||||
const accountData: AccountCookie = cookie
|
||||
? JSON.parse(cookie as string)
|
||||
: null
|
||||
|
||||
// Set up state for error handling
|
||||
const [axiosError, setAxiosError] = useState<AxiosResponse>()
|
||||
const [errorAlertOpen, setErrorAlertOpen] = useState(false)
|
||||
|
||||
// Set up state for view management
|
||||
const { party, grid } = useSnapshot(appState)
|
||||
const [slug, setSlug] = useState()
|
||||
|
|
@ -111,7 +119,15 @@ const CharacterGrid = (props: Props) => {
|
|||
if (party.editable)
|
||||
saveCharacter(party.id, character, position)
|
||||
.then((response) => handleCharacterResponse(response.data))
|
||||
.catch((error) => console.error(error))
|
||||
.catch((error) => {
|
||||
const axiosError = error as AxiosError
|
||||
const response = axiosError.response
|
||||
|
||||
if (response) {
|
||||
setErrorAlertOpen(true)
|
||||
setAxiosError(response)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -482,6 +498,19 @@ const CharacterGrid = (props: Props) => {
|
|||
}
|
||||
|
||||
// Render: JSX components
|
||||
const errorAlert = () => {
|
||||
console.log(axiosError?.status)
|
||||
return (
|
||||
<Alert
|
||||
open={errorAlertOpen}
|
||||
title={axiosError ? `${axiosError.status}` : 'Error'}
|
||||
message={t(`errors.${axiosError?.statusText.toLowerCase()}`)}
|
||||
cancelAction={() => setErrorAlertOpen(false)}
|
||||
cancelActionText={t('buttons.confirm')}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Alert
|
||||
|
|
@ -526,6 +555,7 @@ const CharacterGrid = (props: Props) => {
|
|||
})}
|
||||
</ul>
|
||||
</div>
|
||||
{errorAlert()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import { getCookie } from 'cookies-next'
|
|||
import { useSnapshot } from 'valtio'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
||||
import { AxiosResponse } from 'axios'
|
||||
import { AxiosError, AxiosResponse } from 'axios'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
import Alert from '~components/Alert'
|
||||
import SummonUnit from '~components/SummonUnit'
|
||||
import ExtraSummons from '~components/ExtraSummons'
|
||||
|
||||
|
|
@ -38,6 +39,10 @@ const SummonGrid = (props: Props) => {
|
|||
// Localization
|
||||
const { t } = useTranslation('common')
|
||||
|
||||
// Set up state for error handling
|
||||
const [axiosError, setAxiosError] = useState<AxiosResponse>()
|
||||
const [errorAlertOpen, setErrorAlertOpen] = useState(false)
|
||||
|
||||
// Set up state for view management
|
||||
const { party, grid } = useSnapshot(appState)
|
||||
const [slug, setSlug] = useState()
|
||||
|
|
@ -100,12 +105,12 @@ const SummonGrid = (props: Props) => {
|
|||
saveSummon(party.id, summon, position)
|
||||
.then((response) => handleSummonResponse(response.data))
|
||||
.catch((error) => {
|
||||
const code = error.response.status
|
||||
const data = error.response.data
|
||||
if (code === 422) {
|
||||
if (data.code === 'incompatible_summon_for_position') {
|
||||
// setShowIncompatibleAlert(true)
|
||||
}
|
||||
const axiosError = error as AxiosError
|
||||
const response = axiosError.response
|
||||
|
||||
if (response) {
|
||||
setErrorAlertOpen(true)
|
||||
setAxiosError(response)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -380,6 +385,19 @@ const SummonGrid = (props: Props) => {
|
|||
}
|
||||
|
||||
// Render: JSX components
|
||||
const errorAlert = () => {
|
||||
console.log(axiosError?.status)
|
||||
return (
|
||||
<Alert
|
||||
open={errorAlertOpen}
|
||||
title={axiosError ? `${axiosError.status}` : 'Error'}
|
||||
message={t(`errors.${axiosError?.statusText.toLowerCase()}`)}
|
||||
cancelAction={() => setErrorAlertOpen(false)}
|
||||
cancelActionText={t('buttons.confirm')}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const mainSummonElement = (
|
||||
<div className="LabeledUnit">
|
||||
<div className="Label">{t('summons.main')}</div>
|
||||
|
|
@ -460,6 +478,7 @@ const SummonGrid = (props: Props) => {
|
|||
</div>
|
||||
|
||||
{subAuraSummonElement}
|
||||
{errorAlert()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { getCookie } from 'cookies-next'
|
|||
import { useSnapshot } from 'valtio'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
||||
import { AxiosResponse } from 'axios'
|
||||
import { AxiosError, AxiosResponse } from 'axios'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
import Alert from '~components/Alert'
|
||||
|
|
@ -41,11 +41,15 @@ const WeaponGrid = (props: Props) => {
|
|||
? JSON.parse(cookie as string)
|
||||
: null
|
||||
|
||||
// Set up state for error handling
|
||||
const [axiosError, setAxiosError] = useState<AxiosResponse>()
|
||||
const [errorAlertOpen, setErrorAlertOpen] = useState(false)
|
||||
const [showIncompatibleAlert, setShowIncompatibleAlert] = useState(false)
|
||||
|
||||
// Set up state for view management
|
||||
const { party, grid } = useSnapshot(appState)
|
||||
const [slug, setSlug] = useState()
|
||||
const [modalOpen, setModalOpen] = useState(false)
|
||||
const [showIncompatibleAlert, setShowIncompatibleAlert] = useState(false)
|
||||
|
||||
// Set up state for conflict management
|
||||
const [incoming, setIncoming] = useState<Weapon>()
|
||||
|
|
@ -100,11 +104,21 @@ const WeaponGrid = (props: Props) => {
|
|||
saveWeapon(party.id, weapon, position)
|
||||
.then((response) => handleWeaponResponse(response.data))
|
||||
.catch((error) => {
|
||||
const code = error.response.status
|
||||
const data = error.response.data
|
||||
if (code === 422) {
|
||||
if (data.code === 'incompatible_weapon_for_position') {
|
||||
const axiosError = error as AxiosError
|
||||
const response = axiosError.response
|
||||
|
||||
if (response) {
|
||||
const code = response.status
|
||||
const data = response.data
|
||||
|
||||
if (
|
||||
code === 422 &&
|
||||
data.code === 'incompatible_weapon_for_position'
|
||||
) {
|
||||
setShowIncompatibleAlert(true)
|
||||
} else {
|
||||
setErrorAlertOpen(true)
|
||||
setAxiosError(response)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -362,16 +376,30 @@ const WeaponGrid = (props: Props) => {
|
|||
cancelAction={() => setShowIncompatibleAlert(!showIncompatibleAlert)}
|
||||
cancelActionText={t('buttons.confirm')}
|
||||
message={t('alert.incompatible_weapon')}
|
||||
></Alert>
|
||||
/>
|
||||
) : (
|
||||
''
|
||||
)
|
||||
}
|
||||
|
||||
const errorAlert = () => {
|
||||
console.log(axiosError?.status)
|
||||
return (
|
||||
<Alert
|
||||
open={errorAlertOpen}
|
||||
title={axiosError ? `${axiosError.status}` : 'Error'}
|
||||
message={t(`errors.${axiosError?.statusText.toLowerCase()}`)}
|
||||
cancelAction={() => setErrorAlertOpen(false)}
|
||||
cancelActionText={t('buttons.confirm')}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div id="WeaponGrid">
|
||||
{conflicts ? conflictModal() : ''}
|
||||
{incompatibleAlert()}
|
||||
{errorAlert()}
|
||||
<div id="MainGrid">
|
||||
{mainhandElement}
|
||||
<ul id="Weapons">{weaponGridElement}</ul>
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@
|
|||
},
|
||||
"remove": "Remove from grid"
|
||||
},
|
||||
"errors": {
|
||||
"unauthorized": "You don't have permission to perform that action"
|
||||
},
|
||||
"filters": {
|
||||
"labels": {
|
||||
"element": "Element",
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@
|
|||
"rarity": "レアリティ"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"unauthorized": "行ったアクションを実行する権限がありません"
|
||||
},
|
||||
"header": {
|
||||
"anonymous": "無名",
|
||||
"untitled_team": "{{username}}さんからの無題編成",
|
||||
|
|
|
|||
Loading…
Reference in a new issue