mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-09-11 13:56:29 +02:00
Factoring gsheet read
This commit is contained in:
@@ -1,24 +0,0 @@
|
||||
import { memo } from "react"
|
||||
import { Link } from "react-router-dom"
|
||||
|
||||
import { JavGame } from "../../services/javGames"
|
||||
import styles from "./styles.module.scss"
|
||||
|
||||
interface Props {
|
||||
items: JavGame[]
|
||||
}
|
||||
|
||||
const List = ({ items }: Props) => (
|
||||
<div className={styles.JavGameList}>
|
||||
<h4>JAV Games</h4>
|
||||
<ul>
|
||||
{items.map(({ id, titre }) => (
|
||||
<li key={id}>
|
||||
<Link to={`/UserInfo/${id}`}>{titre}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default memo(List)
|
@@ -22,14 +22,13 @@ describe("<List />", () => {
|
||||
duree: 45,
|
||||
type: "Ambiance",
|
||||
poufpaf: "0-9-2/6-qui-prend-6-nimmt",
|
||||
photo: "https://cf.geekdo-images.com/thumb/img/lzczxR5cw7an7tRWeHdOrRtLyes=/fit-in/200x150/pic772547.jpg",
|
||||
bggPhoto: "",
|
||||
bggId: 432,
|
||||
exemplaires: 1,
|
||||
dispoPret: 1,
|
||||
nonRangee: 0,
|
||||
horodatage: "0000-00-00",
|
||||
ean: "3421272101313",
|
||||
bggPhoto:
|
||||
"https://cf.geekdo-images.com/thumb/img/lzczxR5cw7an7tRWeHdOrRtLyes=/fit-in/200x150/pic772547.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
@@ -2,18 +2,17 @@
|
||||
|
||||
exports[`<List /> renders 1`] = `
|
||||
<div
|
||||
class="JavGameList"
|
||||
class="JeuxJavList"
|
||||
>
|
||||
<h4>
|
||||
JAV Games
|
||||
Jeux JAV
|
||||
</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="/UserInfo/5"
|
||||
>
|
||||
6 qui prend!
|
||||
</a>
|
||||
6 qui prend!
|
||||
- [
|
||||
432
|
||||
]
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
24
src/components/JeuxJavList/index.tsx
Normal file
24
src/components/JeuxJavList/index.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { memo } from "react"
|
||||
// import { Link } from "react-router-dom"
|
||||
|
||||
import { JeuxJav } from "../../services/jeuxJav"
|
||||
import styles from "./styles.module.scss"
|
||||
|
||||
interface Props {
|
||||
items: JeuxJav[]
|
||||
}
|
||||
|
||||
const List = ({ items }: Props) => (
|
||||
<div className={styles.JeuxJavList}>
|
||||
<h4>Jeux JAV</h4>
|
||||
<ul>
|
||||
{items.map(({ id, titre, bggId }) => (
|
||||
<li key={id}>
|
||||
{titre} - [{bggId}]
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default memo(List)
|
@@ -1,7 +1,7 @@
|
||||
import List from "./List"
|
||||
import JavGameList from "./JavGameList"
|
||||
import JeuxJavList from "./JeuxJavList"
|
||||
import Info from "./Info"
|
||||
import ErrorBoundary from "./ErrorBoundary"
|
||||
import Loading from "./Loading"
|
||||
|
||||
export { List, JavGameList, Info, ErrorBoundary, Loading }
|
||||
export { List, JeuxJavList, Info, ErrorBoundary, Loading }
|
||||
|
27
src/gsheets/jeuxJav.ts
Normal file
27
src/gsheets/jeuxJav.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Request, Response, NextFunction } from "express"
|
||||
import _ from "lodash"
|
||||
import { getList } from "./utils"
|
||||
import { JeuxJav } from "../services/jeuxJav"
|
||||
|
||||
export const getJeuxJavList = async (
|
||||
_request: Request,
|
||||
response: Response,
|
||||
_next: NextFunction
|
||||
): Promise<void> => {
|
||||
const list = await getList<JeuxJav>("Jeux JAV")
|
||||
if (list) {
|
||||
response.status(200).json(list)
|
||||
}
|
||||
}
|
||||
|
||||
export const getJeuxJavData = async (
|
||||
_request: Request,
|
||||
response: Response,
|
||||
_next: NextFunction
|
||||
): Promise<void> => {
|
||||
const list = await getList<JeuxJav>("Jeux JAV")
|
||||
const data = _.find(list, { id: 56 })
|
||||
if (data) {
|
||||
response.status(200).json(data)
|
||||
}
|
||||
}
|
@@ -2,7 +2,6 @@ import path from "path"
|
||||
import fs from "fs"
|
||||
import readline from "readline"
|
||||
import _ from "lodash"
|
||||
import { Request, Response, NextFunction } from "express"
|
||||
import { google } from "googleapis"
|
||||
import config from "../config"
|
||||
|
||||
@@ -10,75 +9,33 @@ const SCOPES = ["https://www.googleapis.com/auth/spreadsheets"]
|
||||
const TOKEN_PATH = path.resolve(process.cwd(), "access/token.json")
|
||||
const CRED_PATH = path.resolve(process.cwd(), "access/gsheets.json")
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export const getJAVGameList = async (
|
||||
_request: Request,
|
||||
response: Response,
|
||||
_next: NextFunction
|
||||
): Promise<void> => {
|
||||
export const getList = async <T>(sheetName: string): Promise<T[] | undefined> => {
|
||||
const auth = await authorize(JSON.parse(fs.readFileSync(CRED_PATH, "utf8")))
|
||||
const sheets = google.sheets({ version: "v4", auth })
|
||||
const r = await sheets.spreadsheets.values.get({
|
||||
spreadsheetId: config.GOOGLE_SHEET_ID,
|
||||
range: "JAV Games!A1:Z",
|
||||
range: `${sheetName}!A1:Z`,
|
||||
})
|
||||
|
||||
if (_.isArray(r?.data?.values)) {
|
||||
const list = _.map(r.data.values, (val: any) => ({
|
||||
id: val[0],
|
||||
titre: val[1],
|
||||
}))
|
||||
response.status(200).json(list)
|
||||
const rows = r.data.values as string[][]
|
||||
const keys: string[] = rows[0]
|
||||
rows.shift()
|
||||
const list: T[] = _.map(
|
||||
rows,
|
||||
(row) =>
|
||||
_.reduce(
|
||||
row,
|
||||
(game: any, val: any, collumn: number) => {
|
||||
game[keys[collumn]] = val
|
||||
return game
|
||||
},
|
||||
{}
|
||||
) as T
|
||||
)
|
||||
return list
|
||||
}
|
||||
// if (r?.data?.values) {
|
||||
// const rows: JAVGame[] = r.data.values as JAVGame[]
|
||||
// if (rows) {
|
||||
// if (rows.length) {
|
||||
// console.log('Name, Major:')
|
||||
// // Print columns A and E, which correspond to indices 0 and 4.
|
||||
// rows.map((row) => {
|
||||
// console.log(`${row[0]}, ${row[4]}`)
|
||||
// })
|
||||
// return { data: rows }
|
||||
// } else {
|
||||
// console.log('No data found.')
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export const getJAVGameData = async (
|
||||
_request: Request,
|
||||
response: Response,
|
||||
_next: NextFunction
|
||||
): Promise<void> => {
|
||||
console.log("CRED_PATH", CRED_PATH)
|
||||
console.log("fs.readFileSync(CRED_PATH, 'utf8')")
|
||||
const auth = await authorize(JSON.parse(fs.readFileSync(CRED_PATH, "utf8")))
|
||||
const sheets = google.sheets({ version: "v4", auth })
|
||||
const r = await sheets.spreadsheets.values.get({
|
||||
spreadsheetId: "1pMMKcYx6NXLOqNn6pLHJTPMTOLRYZmSNg2QQcAu7-Pw",
|
||||
range: "Ongoing!A1:T",
|
||||
})
|
||||
|
||||
console.log("r?.data?.values", r?.data?.values)
|
||||
response.status(200).json(r?.data?.values)
|
||||
// if (r?.data?.values) {
|
||||
// const rows: JAVGame[] = r.data.values as JAVGame[]
|
||||
// if (rows) {
|
||||
// if (rows.length) {
|
||||
// console.log('Name, Major:')
|
||||
// // Print columns A and E, which correspond to indices 0 and 4.
|
||||
// rows.map((row) => {
|
||||
// console.log(`${row[0]}, ${row[4]}`)
|
||||
// })
|
||||
// return { data: rows }
|
||||
// } else {
|
||||
// console.log('No data found.')
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return undefined
|
||||
}
|
||||
|
||||
async function authorize(cred: any) {
|
||||
@@ -131,3 +88,5 @@ async function readlineAsync(question: string) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export { SCOPES }
|
@@ -4,8 +4,8 @@ import { useDispatch, useSelector, shallowEqual } from "react-redux"
|
||||
import { Helmet } from "react-helmet"
|
||||
|
||||
import { AppState, AppThunk } from "../../store"
|
||||
import { fetchJavGameListIfNeed } from "../../store/javGameList"
|
||||
import { JavGameList } from "../../components"
|
||||
import { fetchJeuxJavListIfNeed } from "../../store/jeuxJavList"
|
||||
import { JeuxJavList } from "../../components"
|
||||
import styles from "./styles.module.scss"
|
||||
|
||||
export type Props = RouteComponentProps
|
||||
@@ -26,20 +26,20 @@ function useList(stateToProp: (state: AppState) => any, fetchDataIfNeed: () => A
|
||||
|
||||
if (readyStatus === "failure") return <p>Oops, Failed to load list!</p>
|
||||
|
||||
return <JavGameList items={items} />
|
||||
return <JeuxJavList items={items} />
|
||||
}
|
||||
}
|
||||
|
||||
const Home: FC<Props> = (): JSX.Element => (
|
||||
<div className={styles.Home}>
|
||||
<Helmet title="Home" />
|
||||
{useList((state: AppState) => state.javGameList, fetchJavGameListIfNeed)()}
|
||||
{useList((state: AppState) => state.jeuxJavList, fetchJeuxJavListIfNeed)()}
|
||||
</div>
|
||||
)
|
||||
|
||||
// Fetch server-side data here
|
||||
export const loadData = (): AppThunk[] => [
|
||||
fetchJavGameListIfNeed(),
|
||||
fetchJeuxJavListIfNeed(),
|
||||
// More pre-fetched actions...
|
||||
]
|
||||
|
||||
|
@@ -4,13 +4,13 @@
|
||||
import { render } from "@testing-library/react"
|
||||
import { MemoryRouter } from "react-router-dom"
|
||||
|
||||
import { fetchJavGameListIfNeed } from "../../../store/javGameList"
|
||||
import { fetchJeuxJavListIfNeed } from "../../../store/jeuxJavList"
|
||||
import mockStore from "../../../utils/mockStore"
|
||||
import Home from "../Home"
|
||||
|
||||
describe("<Home />", () => {
|
||||
const renderHelper = (reducer = { readyStatus: "invalid" }) => {
|
||||
const { dispatch, ProviderWithStore } = mockStore({ javGameList: reducer })
|
||||
const { dispatch, ProviderWithStore } = mockStore({ jeuxJavList: reducer })
|
||||
const { container } = render(
|
||||
<ProviderWithStore>
|
||||
<MemoryRouter>
|
||||
@@ -28,7 +28,7 @@ describe("<Home />", () => {
|
||||
const { dispatch } = renderHelper()
|
||||
|
||||
expect(dispatch).toHaveBeenCalledTimes(1)
|
||||
expect(dispatch.mock.calls[0][0].toString()).toBe(fetchJavGameListIfNeed().toString())
|
||||
expect(dispatch.mock.calls[0][0].toString()).toBe(fetchJeuxJavListIfNeed().toString())
|
||||
})
|
||||
|
||||
it("renders the loading status if data invalid", () => {
|
||||
|
@@ -15,18 +15,17 @@ exports[`<Home /> renders the <List /> if loading was successful 1`] = `
|
||||
class="Home"
|
||||
>
|
||||
<div
|
||||
class="JavGameList"
|
||||
class="JeuxJavList"
|
||||
>
|
||||
<h4>
|
||||
JAV Games
|
||||
Jeux JAV
|
||||
</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="/UserInfo/5"
|
||||
>
|
||||
6 qui prend!
|
||||
</a>
|
||||
6 qui prend!
|
||||
- [
|
||||
432
|
||||
]
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@@ -10,7 +10,7 @@ import chalk from "chalk"
|
||||
import devServer from "./devServer"
|
||||
import ssr from "./ssr"
|
||||
|
||||
import { getJAVGameList } from "../gsheets/jav"
|
||||
import { getJeuxJavList } from "../gsheets/jeuxJav"
|
||||
import config from "../config"
|
||||
|
||||
const app = express()
|
||||
@@ -31,7 +31,7 @@ app.use(express.static(path.resolve(process.cwd(), "public")))
|
||||
if (__DEV__) devServer(app)
|
||||
|
||||
// Google Sheets requests
|
||||
app.get("/javGames", getJAVGameList)
|
||||
app.get("/JeuxJav", getJeuxJavList)
|
||||
|
||||
// Use React server-side rendering middleware
|
||||
app.get("*", ssr)
|
||||
|
@@ -2,7 +2,7 @@ import axios from "axios"
|
||||
|
||||
import config from "../config"
|
||||
|
||||
export interface JavGame {
|
||||
export interface JeuxJav {
|
||||
id: number
|
||||
titre: string
|
||||
auteur: string
|
||||
@@ -12,36 +12,34 @@ export interface JavGame {
|
||||
duree: number
|
||||
type: "Ambiance" | "Famille" | "Expert" | ""
|
||||
poufpaf: string
|
||||
photo: string
|
||||
bggPhoto: string
|
||||
bggId: number
|
||||
exemplaires: number // Defaults to 1
|
||||
dispoPret: number
|
||||
nonRangee: number
|
||||
horodatage: string
|
||||
ean: string
|
||||
bggPhoto: string
|
||||
}
|
||||
|
||||
export interface JavGameList {
|
||||
data?: JavGame[]
|
||||
export interface JeuxJavList {
|
||||
data?: JeuxJav[]
|
||||
error?: Error
|
||||
}
|
||||
|
||||
export interface JavGameData {
|
||||
data?: JavGame
|
||||
export interface JeuxJavData {
|
||||
data?: JeuxJav
|
||||
error?: Error
|
||||
}
|
||||
|
||||
export const getJavGameList = async (): Promise<JavGameList> => {
|
||||
export const getJeuxJavList = async (): Promise<JeuxJavList> => {
|
||||
try {
|
||||
const { data } = await axios.get(`${config.API_URL}/javGames`)
|
||||
const { data } = await axios.get(`${config.API_URL}/JeuxJav`)
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
|
||||
export const getJavGameData = async (id: string): Promise<JavGameData> => {
|
||||
export const getJeuxJavData = async (id: string): Promise<JeuxJavData> => {
|
||||
try {
|
||||
const { data } = await axios.get(`${config.API_URL}/users/${id}`)
|
||||
return { data }
|
@@ -1,13 +1,13 @@
|
||||
import axios from "axios"
|
||||
|
||||
import mockStore from "../../utils/mockStore"
|
||||
import javGameList, {
|
||||
import JeuxJavList, {
|
||||
initialState,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
fetchJavGameList,
|
||||
} from "../javGameList"
|
||||
fetchJeuxJavList,
|
||||
} from "../jeuxJavList"
|
||||
|
||||
jest.mock("axios")
|
||||
|
||||
@@ -34,14 +34,14 @@ const mockData = [
|
||||
]
|
||||
const mockError = "Oops! Something went wrong."
|
||||
|
||||
describe("javGameList reducer", () => {
|
||||
describe("JeuxJavList reducer", () => {
|
||||
it("should handle initial state", () => {
|
||||
// @ts-expect-error
|
||||
expect(javGameList(undefined, {})).toEqual(initialState)
|
||||
expect(JeuxJavList(undefined, {})).toEqual(initialState)
|
||||
})
|
||||
|
||||
it("should handle requesting correctly", () => {
|
||||
expect(javGameList(undefined, { type: getRequesting.type })).toEqual({
|
||||
expect(JeuxJavList(undefined, { type: getRequesting.type })).toEqual({
|
||||
readyStatus: "request",
|
||||
items: [],
|
||||
error: null,
|
||||
@@ -49,7 +49,7 @@ describe("javGameList reducer", () => {
|
||||
})
|
||||
|
||||
it("should handle success correctly", () => {
|
||||
expect(javGameList(undefined, { type: getSuccess.type, payload: mockData })).toEqual({
|
||||
expect(JeuxJavList(undefined, { type: getSuccess.type, payload: mockData })).toEqual({
|
||||
...initialState,
|
||||
readyStatus: "success",
|
||||
items: mockData,
|
||||
@@ -57,7 +57,7 @@ describe("javGameList reducer", () => {
|
||||
})
|
||||
|
||||
it("should handle failure correctly", () => {
|
||||
expect(javGameList(undefined, { type: getFailure.type, payload: mockError })).toEqual({
|
||||
expect(JeuxJavList(undefined, { type: getFailure.type, payload: mockError })).toEqual({
|
||||
...initialState,
|
||||
readyStatus: "failure",
|
||||
error: mockError,
|
||||
@@ -65,8 +65,8 @@ describe("javGameList reducer", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("javGameList action", () => {
|
||||
it("fetches javGame list successful", async () => {
|
||||
describe("JeuxJavList action", () => {
|
||||
it("fetches JeuxJav list successful", async () => {
|
||||
const { dispatch, getActions } = mockStore()
|
||||
const expectedActions = [
|
||||
{ type: getRequesting.type },
|
||||
@@ -76,11 +76,11 @@ describe("javGameList action", () => {
|
||||
// @ts-expect-error
|
||||
axios.get.mockResolvedValue({ data: mockData })
|
||||
|
||||
await dispatch(fetchJavGameList())
|
||||
await dispatch(fetchJeuxJavList())
|
||||
expect(getActions()).toEqual(expectedActions)
|
||||
})
|
||||
|
||||
it("fetches javGame list failed", async () => {
|
||||
it("fetches JeuxJav list failed", async () => {
|
||||
const { dispatch, getActions } = mockStore()
|
||||
const expectedActions = [
|
||||
{ type: getRequesting.type },
|
||||
@@ -90,7 +90,7 @@ describe("javGameList action", () => {
|
||||
// @ts-expect-error
|
||||
axios.get.mockRejectedValue({ message: mockError })
|
||||
|
||||
await dispatch(fetchJavGameList())
|
||||
await dispatch(fetchJeuxJavList())
|
||||
expect(getActions()).toEqual(expectedActions)
|
||||
})
|
||||
})
|
@@ -1,57 +0,0 @@
|
||||
import { PayloadAction, createSlice } from "@reduxjs/toolkit"
|
||||
|
||||
import { JavGame, getJavGameList } from "../services/javGames"
|
||||
import { AppThunk, AppState } from "."
|
||||
|
||||
interface JavGameList {
|
||||
readyStatus: string
|
||||
items: JavGame[]
|
||||
error: string | null
|
||||
}
|
||||
|
||||
export const initialState: JavGameList = {
|
||||
readyStatus: "invalid",
|
||||
items: [],
|
||||
error: null,
|
||||
}
|
||||
|
||||
const javGameList = createSlice({
|
||||
name: "javGameList",
|
||||
initialState,
|
||||
reducers: {
|
||||
getRequesting: (state: JavGameList) => {
|
||||
state.readyStatus = "request"
|
||||
},
|
||||
getSuccess: (state, { payload }: PayloadAction<JavGame[]>) => {
|
||||
state.readyStatus = "success"
|
||||
state.items = payload
|
||||
},
|
||||
getFailure: (state, { payload }: PayloadAction<string>) => {
|
||||
state.readyStatus = "failure"
|
||||
state.error = payload
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export default javGameList.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = javGameList.actions
|
||||
|
||||
export const fetchJavGameList = (): AppThunk => async (dispatch) => {
|
||||
dispatch(getRequesting())
|
||||
|
||||
const { error, data } = await getJavGameList()
|
||||
|
||||
if (error) {
|
||||
dispatch(getFailure(error.message))
|
||||
} else {
|
||||
dispatch(getSuccess(data as JavGame[]))
|
||||
}
|
||||
}
|
||||
|
||||
const shouldFetchJavGameList = (state: AppState) => state.javGameList.readyStatus !== "success"
|
||||
|
||||
export const fetchJavGameListIfNeed = (): AppThunk => (dispatch, getState) => {
|
||||
if (shouldFetchJavGameList(getState())) return dispatch(fetchJavGameList())
|
||||
|
||||
return null
|
||||
}
|
57
src/store/jeuxJavList.ts
Normal file
57
src/store/jeuxJavList.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { PayloadAction, createSlice } from "@reduxjs/toolkit"
|
||||
|
||||
import { JeuxJav, getJeuxJavList } from "../services/jeuxJav"
|
||||
import { AppThunk, AppState } from "."
|
||||
|
||||
interface JeuxJavList {
|
||||
readyStatus: string
|
||||
items: JeuxJav[]
|
||||
error: string | null
|
||||
}
|
||||
|
||||
export const initialState: JeuxJavList = {
|
||||
readyStatus: "invalid",
|
||||
items: [],
|
||||
error: null,
|
||||
}
|
||||
|
||||
const jeuxJavList = createSlice({
|
||||
name: "jeuxJavList",
|
||||
initialState,
|
||||
reducers: {
|
||||
getRequesting: (state: JeuxJavList) => {
|
||||
state.readyStatus = "request"
|
||||
},
|
||||
getSuccess: (state, { payload }: PayloadAction<JeuxJav[]>) => {
|
||||
state.readyStatus = "success"
|
||||
state.items = payload
|
||||
},
|
||||
getFailure: (state, { payload }: PayloadAction<string>) => {
|
||||
state.readyStatus = "failure"
|
||||
state.error = payload
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export default jeuxJavList.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = jeuxJavList.actions
|
||||
|
||||
export const fetchJeuxJavList = (): AppThunk => async (dispatch) => {
|
||||
dispatch(getRequesting())
|
||||
|
||||
const { error, data } = await getJeuxJavList()
|
||||
|
||||
if (error) {
|
||||
dispatch(getFailure(error.message))
|
||||
} else {
|
||||
dispatch(getSuccess(data as JeuxJav[]))
|
||||
}
|
||||
}
|
||||
|
||||
const shouldFetchJeuxJavList = (state: AppState) => state.jeuxJavList.readyStatus !== "success"
|
||||
|
||||
export const fetchJeuxJavListIfNeed = (): AppThunk => (dispatch, getState) => {
|
||||
if (shouldFetchJeuxJavList(getState())) return dispatch(fetchJeuxJavList())
|
||||
|
||||
return null
|
||||
}
|
@@ -3,14 +3,14 @@ import { connectRouter } from "connected-react-router"
|
||||
|
||||
import userList from "./userList"
|
||||
import userData from "./userData"
|
||||
import javGameList from "./javGameList"
|
||||
import jeuxJavList from "./jeuxJavList"
|
||||
|
||||
// Use inferred return type for making correctly Redux types
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default (history: History) => ({
|
||||
userList,
|
||||
userData,
|
||||
javGameList,
|
||||
jeuxJavList,
|
||||
router: connectRouter(history) as any,
|
||||
// Register more reducers...
|
||||
})
|
||||
|
Reference in New Issue
Block a user