バグ修正(#253) #254

Closed
みてるぞ wants to merge 25 commits from feature/253 into main
16 changed files with 74 additions and 132 deletions
Showing only changes of commit 57f28e4e5e - Show all commits
+5 -8
View File
@@ -1,12 +1,11 @@
import axios from 'axios' import axios from 'axios'
import toCamel from 'camelcase-keys'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { BrowserRouter, Navigate, Route, Routes, useLocation } from 'react-router-dom' import { BrowserRouter, Navigate, Route, Routes, useLocation } from 'react-router-dom'
import RouteBlockerOverlay from '@/components/RouteBlockerOverlay' import RouteBlockerOverlay from '@/components/RouteBlockerOverlay'
import TopNav from '@/components/TopNav' import TopNav from '@/components/TopNav'
import { Toaster } from '@/components/ui/toaster' import { Toaster } from '@/components/ui/toaster'
import { API_BASE_URL } from '@/config' import { apiPost } from '@/lib/api'
import NicoTagListPage from '@/pages/tags/NicoTagListPage' import NicoTagListPage from '@/pages/tags/NicoTagListPage'
import NotFound from '@/pages/NotFound' import NotFound from '@/pages/NotFound'
import PostDetailPage from '@/pages/posts/PostDetailPage' import PostDetailPage from '@/pages/posts/PostDetailPage'
@@ -40,12 +39,11 @@ export default (() => {
useEffect (() => { useEffect (() => {
const createUser = async () => { const createUser = async () => {
const res = await axios.post (`${ API_BASE_URL }/users`) const data = await apiPost<{ code: string; user: User }> ('/users')
const data = res.data as { code: string; user: any }
if (data.code) if (data.code)
{ {
localStorage.setItem ('user_code', data.code) localStorage.setItem ('user_code', data.code)
setUser (toCamel (data.user, { deep: true }) as User) setUser (data.user)
} }
} }
@@ -55,10 +53,9 @@ export default (() => {
void (async () => { void (async () => {
try try
{ {
const res = await axios.post (`${ API_BASE_URL }/users/verify`, { code }) const data = await apiPost<{ valid: boolean; user: User }> ('/users/verify', { code })
const data = res.data as { valid: boolean, user: any }
if (data.valid) if (data.valid)
setUser (toCamel (data.user, { deep: true })) setUser (data.user)
else else
await createUser () await createUser ()
} }
+2 -5
View File
@@ -1,11 +1,9 @@
import axios from 'axios'
import toCamel from 'camelcase-keys'
import { useRef, useState } from 'react' import { useRef, useState } from 'react'
import TagSearchBox from '@/components/TagSearchBox' import TagSearchBox from '@/components/TagSearchBox'
import Label from '@/components/common/Label' import Label from '@/components/common/Label'
import TextArea from '@/components/common/TextArea' import TextArea from '@/components/common/TextArea'
import { API_BASE_URL } from '@/config' import { apiGet } from '@/lib/api'
import type { FC, SyntheticEvent } from 'react' import type { FC, SyntheticEvent } from 'react'
@@ -59,8 +57,7 @@ export default (({ tags, setTags }: Props) => {
const recompute = async (pos: number, v: string = tags) => { const recompute = async (pos: number, v: string = tags) => {
const { start, end, token } = getTokenAt (v, pos) const { start, end, token } = getTokenAt (v, pos)
setBounds ({ start, end }) setBounds ({ start, end })
const res = await axios.get (`${ API_BASE_URL }/tags/autocomplete`, { params: { q: token } }) const data = await apiGet<Tag[]> ('/tags/autocomplete', { params: { q: token } })
const data = toCamel (res.data as any, { deep: true }) as Tag[]
setSuggestions (data.filter (t => t.postCount > 0)) setSuggestions (data.filter (t => t.postCount > 0))
setSuggestionsVsbl (suggestions.length > 0) setSuggestionsVsbl (suggestions.length > 0)
} }
+6 -27
View File
@@ -6,8 +6,6 @@ import { DndContext,
useSensor, useSensor,
useSensors } from '@dnd-kit/core' useSensors } from '@dnd-kit/core'
import { restrictToWindowEdges } from '@dnd-kit/modifiers' import { restrictToWindowEdges } from '@dnd-kit/modifiers'
import axios from 'axios'
import toCamel from 'camelcase-keys'
import { AnimatePresence, motion } from 'framer-motion' import { AnimatePresence, motion } from 'framer-motion'
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
@@ -19,8 +17,8 @@ import SectionTitle from '@/components/common/SectionTitle'
import SubsectionTitle from '@/components/common/SubsectionTitle' import SubsectionTitle from '@/components/common/SubsectionTitle'
import SidebarComponent from '@/components/layout/SidebarComponent' import SidebarComponent from '@/components/layout/SidebarComponent'
import { toast } from '@/components/ui/use-toast' import { toast } from '@/components/ui/use-toast'
import { API_BASE_URL } from '@/config'
import { CATEGORIES } from '@/consts' import { CATEGORIES } from '@/consts'
import { apiDelete, apiGet, apiPatch, apiPost } from '@/lib/api'
import type { DragEndEvent } from '@dnd-kit/core' import type { DragEndEvent } from '@dnd-kit/core'
import type { FC, MutableRefObject, ReactNode } from 'react' import type { FC, MutableRefObject, ReactNode } from 'react'
@@ -132,10 +130,7 @@ const changeCategory = async (
tagId: number, tagId: number,
category: Category, category: Category,
): Promise<void> => { ): Promise<void> => {
await axios.patch ( await apiPatch (`/tags/${ tagId }`, { category })
`${ API_BASE_URL }/tags/${ tagId }`,
{ category },
{ headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
} }
@@ -170,12 +165,7 @@ export default (({ post }: Props) => {
if (!(post)) if (!(post))
return return
const res = await axios.get ( setTags (buildTagByCategory (await apiGet<Post> (`/posts/${ post.id }`)))
`${ API_BASE_URL }/posts/${ post.id }`,
{ headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
const data = toCamel (res.data as any, { deep: true }) as Post
setTags (buildTagByCategory (data))
} }
const onDragEnd = async (e: DragEndEvent) => { const onDragEnd = async (e: DragEndEvent) => {
@@ -216,16 +206,9 @@ export default (({ post }: Props) => {
return return
if (fromParentId != null) if (fromParentId != null)
{ await apiDelete (`/tags/${ fromParentId }/children/${ childId }`)
await axios.delete (
`${ API_BASE_URL }/tags/${ fromParentId }/children/${ childId }`,
{ headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
}
await axios.post ( await apiPost (`/tags/${ parentId }/children/${ childId }`, { })
`${ API_BASE_URL }/tags/${ parentId }/children/${ childId }`,
{ },
{ headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
await reloadTags () await reloadTags ()
toast ({ toast ({
@@ -245,11 +228,7 @@ export default (({ post }: Props) => {
await changeCategory (childId, cat) await changeCategory (childId, cat)
if (fromParentId != null) if (fromParentId != null)
{ await apiDelete (`/tags/${ fromParentId }/children/${ childId }`)
await axios.delete (
`${ API_BASE_URL }/tags/${ fromParentId }/children/${ childId }`,
{ headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
}
const fromParent = fromParentId == null ? null : findTag (tags, fromParentId) const fromParent = fromParentId == null ? null : findTag (tags, fromParentId)
+7 -5
View File
@@ -1,16 +1,16 @@
import axios from 'axios'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import PrefetchLink from '@/components/PrefetchLink' import PrefetchLink from '@/components/PrefetchLink'
import { API_BASE_URL } from '@/config'
import { LIGHT_COLOUR_SHADE, DARK_COLOUR_SHADE, TAG_COLOUR } from '@/consts' import { LIGHT_COLOUR_SHADE, DARK_COLOUR_SHADE, TAG_COLOUR } from '@/consts'
import { apiGet } from '@/lib/api'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import type { ComponentProps, FC, HTMLAttributes } from 'react' import type { ComponentProps, FC, HTMLAttributes } from 'react'
import type { Tag } from '@/types' import type { Tag } from '@/types'
type CommonProps = { tag: Tag type CommonProps = {
tag: Tag
nestLevel?: number nestLevel?: number
withWiki?: boolean withWiki?: boolean
withCount?: boolean withCount?: boolean
@@ -26,7 +26,9 @@ type PropsWithoutLink =
& { linkFlg: false } & { linkFlg: false }
& Partial<HTMLAttributes<HTMLSpanElement>> & Partial<HTMLAttributes<HTMLSpanElement>>
type Props = PropsWithLink | PropsWithoutLink type Props =
| PropsWithLink
| PropsWithoutLink
export default (({ tag, export default (({ tag,
@@ -49,7 +51,7 @@ export default (({ tag,
try try
{ {
await axios.get (`${ API_BASE_URL }/wiki/title/${ encodeURIComponent (tagName) }/exists`) await apiGet (`/wiki/title/${ encodeURIComponent (tagName) }/exists`)
setHavingWiki (true) setHavingWiki (true)
} }
catch catch
+6 -9
View File
@@ -1,13 +1,11 @@
import axios from 'axios' import { useEffect, useState } from 'react'
import toCamel from 'camelcase-keys'
import React, { useEffect, useState } from 'react'
import { useNavigate, useLocation } from 'react-router-dom' import { useNavigate, useLocation } from 'react-router-dom'
import { API_BASE_URL } from '@/config' import { apiGet } from '@/lib/api'
import TagSearchBox from './TagSearchBox' import TagSearchBox from './TagSearchBox'
import type { FC } from 'react' import type { ChangeEvent, FC, KeyboardEvent } from 'react'
import type { Tag } from '@/types' import type { Tag } from '@/types'
@@ -21,7 +19,7 @@ export default (() => {
const [suggestions, setSuggestions] = useState<Tag[]> ([]) const [suggestions, setSuggestions] = useState<Tag[]> ([])
const [suggestionsVsbl, setSuggestionsVsbl] = useState (false) const [suggestionsVsbl, setSuggestionsVsbl] = useState (false)
const whenChanged = async (ev: React.ChangeEvent<HTMLInputElement>) => { const whenChanged = async (ev: ChangeEvent<HTMLInputElement>) => {
setSearch (ev.target.value) setSearch (ev.target.value)
const q = ev.target.value.trim ().split (' ').at (-1) const q = ev.target.value.trim ().split (' ').at (-1)
@@ -31,14 +29,13 @@ export default (() => {
return return
} }
const res = await axios.get (`${ API_BASE_URL }/tags/autocomplete`, { params: { q } }) const data = await apiGet<Tag[]> ('/tags/autocomplete', { params: { q } })
const data = toCamel (res.data, { deep: true }) as Tag[]
setSuggestions (data.filter (t => t.postCount > 0)) setSuggestions (data.filter (t => t.postCount > 0))
if (suggestions.length > 0) if (suggestions.length > 0)
setSuggestionsVsbl (true) setSuggestionsVsbl (true)
} }
const handleKeyDown = (ev: React.KeyboardEvent<HTMLInputElement>) => { const handleKeyDown = (ev: KeyboardEvent<HTMLInputElement>) => {
switch (ev.key) switch (ev.key)
{ {
case 'ArrowDown': case 'ArrowDown':
+3 -4
View File
@@ -1,4 +1,3 @@
import axios from 'axios'
import { AnimatePresence, motion } from 'framer-motion' import { AnimatePresence, motion } from 'framer-motion'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { useLocation, useNavigate } from 'react-router-dom' import { useLocation, useNavigate } from 'react-router-dom'
@@ -7,8 +6,8 @@ import TagLink from '@/components/TagLink'
import TagSearch from '@/components/TagSearch' import TagSearch from '@/components/TagSearch'
import SectionTitle from '@/components/common/SectionTitle' import SectionTitle from '@/components/common/SectionTitle'
import SidebarComponent from '@/components/layout/SidebarComponent' import SidebarComponent from '@/components/layout/SidebarComponent'
import { API_BASE_URL } from '@/config'
import { CATEGORIES } from '@/consts' import { CATEGORIES } from '@/consts'
import { apiGet } from '@/lib/api'
import type { FC, MouseEvent } from 'react' import type { FC, MouseEvent } from 'react'
@@ -77,10 +76,10 @@ export default (({ posts, onClick }: Props) => {
void ((async () => { void ((async () => {
try try
{ {
const { data } = await axios.get (`${ API_BASE_URL }/posts/random`, const data = await apiGet<Post> ('/posts/random',
{ params: { tags: tagsQuery.split (' ').filter (e => e !== '').join (' '), { params: { tags: tagsQuery.split (' ').filter (e => e !== '').join (' '),
match: (anyFlg ? 'any' : 'all') } }) match: (anyFlg ? 'any' : 'all') } })
navigate (`/posts/${ (data as Post).id }`) navigate (`/posts/${ data.id }`)
} }
catch catch
{ {
+2 -5
View File
@@ -1,5 +1,3 @@
import axios from 'axios'
import toCamel from 'camelcase-keys'
import { useEffect, useMemo, useState } from 'react' import { useEffect, useMemo, useState } from 'react'
import ReactMarkdown from 'react-markdown' import ReactMarkdown from 'react-markdown'
import remarkGFM from 'remark-gfm' import remarkGFM from 'remark-gfm'
@@ -7,7 +5,7 @@ import remarkGFM from 'remark-gfm'
import PrefetchLink from '@/components/PrefetchLink' import PrefetchLink from '@/components/PrefetchLink'
import SectionTitle from '@/components/common/SectionTitle' import SectionTitle from '@/components/common/SectionTitle'
import SubsectionTitle from '@/components/common/SubsectionTitle' import SubsectionTitle from '@/components/common/SubsectionTitle'
import { API_BASE_URL } from '@/config' import { apiGet } from '@/lib/api'
import remarkWikiAutoLink from '@/lib/remark-wiki-autolink' import remarkWikiAutoLink from '@/lib/remark-wiki-autolink'
import type { FC } from 'react' import type { FC } from 'react'
@@ -43,8 +41,7 @@ export default (({ title, body }: Props) => {
void (async () => { void (async () => {
try try
{ {
const res = await axios.get (`${ API_BASE_URL }/wiki`) const data = await apiGet<WikiPage[]> ('/wiki')
const data: WikiPage[] = toCamel (res.data as any, { deep: true })
setPageNames (data.map (page => page.title).sort ((a, b) => b.length - a.length)) setPageNames (data.map (page => page.title).sort ((a, b) => b.length - a.length))
} }
catch catch
@@ -1,5 +1,3 @@
import axios from 'axios'
import toCamel from 'camelcase-keys'
import { useState } from 'react' import { useState } from 'react'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
@@ -8,7 +6,7 @@ import { Dialog,
DialogTitle } from '@/components/ui/dialog' DialogTitle } from '@/components/ui/dialog'
import { Input } from '@/components/ui/input' import { Input } from '@/components/ui/input'
import { toast } from '@/components/ui/use-toast' import { toast } from '@/components/ui/use-toast'
import { API_BASE_URL } from '@/config' import { apiPost } from '@/lib/api'
import type { User } from '@/types' import type { User } from '@/types'
@@ -26,12 +24,12 @@ export default ({ visible, onVisibleChange, setUser }: Props) => {
try try
{ {
const res = await axios.post (`${ API_BASE_URL }/users/verify`, { code: inputCode }) const data = await apiPost<{ valid: boolean; user: User }> (
const data = res.data as { valid: boolean; user: any } '/users/verify', { code: inputCode })
if (data.valid) if (data.valid)
{ {
localStorage.setItem ('user_code', inputCode) localStorage.setItem ('user_code', inputCode)
setUser (toCamel (data.user, { deep: true })) setUser (data.user)
toast ({ title: '引継ぎ成功!' }) toast ({ title: '引継ぎ成功!' })
onVisibleChange (false) onVisibleChange (false)
} }
@@ -1,11 +1,9 @@
import axios from 'axios'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { Dialog, import { Dialog,
DialogContent, DialogContent,
DialogTitle } from '@/components/ui/dialog' DialogTitle } from '@/components/ui/dialog'
import { toast } from '@/components/ui/use-toast' import { toast } from '@/components/ui/use-toast'
import { API_BASE_URL } from '@/config' import { apiPost } from '@/lib/api'
import type { User } from '@/types' import type { User } from '@/types'
@@ -23,10 +21,8 @@ export default ({ visible, onVisibleChange, user, setUser }: Props) => {
if (!(confirm ('引継ぎコードを再発行しますか?\n再発行するとほかのブラウザからはログアウトされます.'))) if (!(confirm ('引継ぎコードを再発行しますか?\n再発行するとほかのブラウザからはログアウトされます.')))
return return
const res = await axios.post (`${ API_BASE_URL }/users/code/renew`, { }, { headers: { const data = await apiPost<{ code: string }> ('/users/code/renew', { },
'Content-Type': 'multipart/form-data', { headers: { 'Content-Type': 'multipart/form-data' } })
'X-Transfer-Code': localStorage.getItem ('user_code') || '' } })
const data = res.data as { code: string }
if (data.code) if (data.code)
{ {
localStorage.setItem ('user_code', data.code) localStorage.setItem ('user_code', data.code)
+2 -1
View File
@@ -5,7 +5,8 @@ import { API_BASE_URL } from '@/config'
type Opt = { type Opt = {
params?: Record<string, unknown> params?: Record<string, unknown>
headers?: Record<string, string> } headers?: Record<string, string>
responseType?: 'blob' }
const client = axios.create ({ baseURL: API_BASE_URL }) const client = axios.create ({ baseURL: API_BASE_URL })
+6 -14
View File
@@ -1,4 +1,3 @@
import axios from 'axios'
import { useEffect, useState, useRef } from 'react' import { useEffect, useState, useRef } from 'react'
import { Helmet } from 'react-helmet-async' import { Helmet } from 'react-helmet-async'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
@@ -11,7 +10,8 @@ import PageTitle from '@/components/common/PageTitle'
import MainArea from '@/components/layout/MainArea' import MainArea from '@/components/layout/MainArea'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { toast } from '@/components/ui/use-toast' import { toast } from '@/components/ui/use-toast'
import { API_BASE_URL, SITE_TITLE } from '@/config' import { SITE_TITLE } from '@/config'
import { apiGet, apiPost } from '@/lib/api'
import Forbidden from '@/pages/Forbidden' import Forbidden from '@/pages/Forbidden'
import type { FC } from 'react' import type { FC } from 'react'
@@ -55,9 +55,7 @@ export default (({ user }: Props) => {
try try
{ {
await axios.post (`${ API_BASE_URL }/posts`, formData, { headers: { await apiPost ('/posts', formData, { headers: { 'Content-Type': 'multipart/form-data' } })
'Content-Type': 'multipart/form-data',
'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
toast ({ title: '投稿成功!' }) toast ({ title: '投稿成功!' })
navigate ('/posts') navigate ('/posts')
} }
@@ -91,10 +89,7 @@ export default (({ user }: Props) => {
const fetchTitle = async () => { const fetchTitle = async () => {
setTitle ('') setTitle ('')
setTitleLoading (true) setTitleLoading (true)
const res = await axios.get (`${ API_BASE_URL }/preview/title`, { const data = await apiGet<{ title: string }> ('/preview/title', { params: { url } })
params: { url },
headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') || '' } })
const data = res.data as { title: string }
setTitle (data.title || '') setTitle (data.title || '')
setTitleLoading (false) setTitleLoading (false)
} }
@@ -105,11 +100,8 @@ export default (({ user }: Props) => {
setThumbnailLoading (true) setThumbnailLoading (true)
if (thumbnailPreview) if (thumbnailPreview)
URL.revokeObjectURL (thumbnailPreview) URL.revokeObjectURL (thumbnailPreview)
const res = await axios.get (`${ API_BASE_URL }/preview/thumbnail`, { const data = await apiGet<Blob> ('/preview/thumbnail',
params: { url }, { params: { url }, responseType: 'blob' })
headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') || '' },
responseType: 'blob' })
const data = res.data as Blob
const imageURL = URL.createObjectURL (data) const imageURL = URL.createObjectURL (data)
setThumbnailPreview (imageURL) setThumbnailPreview (imageURL)
setThumbnailFile (new File ([data], setThumbnailFile (new File ([data],
+6 -11
View File
@@ -1,5 +1,3 @@
import axios from 'axios'
import toCamel from 'camelcase-keys'
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
import { Helmet } from 'react-helmet-async' import { Helmet } from 'react-helmet-async'
@@ -8,7 +6,8 @@ import SectionTitle from '@/components/common/SectionTitle'
import TextArea from '@/components/common/TextArea' import TextArea from '@/components/common/TextArea'
import MainArea from '@/components/layout/MainArea' import MainArea from '@/components/layout/MainArea'
import { toast } from '@/components/ui/use-toast' import { toast } from '@/components/ui/use-toast'
import { API_BASE_URL, SITE_TITLE } from '@/config' import { SITE_TITLE } from '@/config'
import { apiGet, apiPut } from '@/lib/api'
import type { NicoTag, Tag, User } from '@/types' import type { NicoTag, Tag, User } from '@/types'
@@ -29,10 +28,8 @@ export default ({ user }: Props) => {
const loadMore = async (withCursor: boolean) => { const loadMore = async (withCursor: boolean) => {
setLoading (true) setLoading (true)
const res = await axios.get (`${ API_BASE_URL }/tags/nico`, { const data = await apiGet<{ tags: NicoTag[]; nextCursor: string }> (
params: { ...(withCursor ? { cursor } : { }) } }) '/tags/nico', { params: withCursor ? { cursor } : { } })
const data = toCamel (res.data as any, { deep: true }) as { tags: NicoTag[]
nextCursor: string }
setNicoTags (tags => [...(withCursor ? tags : []), ...data.tags]) setNicoTags (tags => [...(withCursor ? tags : []), ...data.tags])
setCursor (data.nextCursor) setCursor (data.nextCursor)
@@ -53,10 +50,8 @@ export default ({ user }: Props) => {
const formData = new FormData const formData = new FormData
formData.append ('tags', rawTags[id]) formData.append ('tags', rawTags[id])
const res = await axios.put (`${ API_BASE_URL }/tags/nico/${ id }`, formData, { headers: { const data = await apiPut<Tag[]> (`/tags/nico/${ id }`, formData,
'Content-Type': 'multipart/form-data', { headers: { 'Content-Type': 'multipart/form-data' } })
'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
const data = toCamel (res.data as any, { deep: true }) as Tag[]
setNicoTags (nicoTags => { setNicoTags (nicoTags => {
nicoTags.find (t => t.id === id)!.linkedTags = data nicoTags.find (t => t.id === id)!.linkedTags = data
return [...nicoTags] return [...nicoTags]
+5 -6
View File
@@ -1,4 +1,3 @@
import axios from 'axios'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Helmet } from 'react-helmet-async' import { Helmet } from 'react-helmet-async'
@@ -10,7 +9,8 @@ import InheritDialogue from '@/components/users/InheritDialogue'
import UserCodeDialogue from '@/components/users/UserCodeDialogue' import UserCodeDialogue from '@/components/users/UserCodeDialogue'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { toast } from '@/components/ui/use-toast' import { toast } from '@/components/ui/use-toast'
import { API_BASE_URL, SITE_TITLE } from '@/config' import { SITE_TITLE } from '@/config'
import { apiPut } from '@/lib/api'
import type { User } from '@/types' import type { User } from '@/types'
@@ -32,10 +32,9 @@ export default ({ user, setUser }: Props) => {
try try
{ {
const res = await axios.put (`${ API_BASE_URL }/users/${ user.id }`, formData, { const data = await apiPut<User> (
headers: { 'Content-Type': 'multipart/form-data', `/users/${ user.id }`, formData,
'X-Transfer-Code': localStorage.getItem ('user_code') || '' } }) { headers: { 'Content-Type': 'multipart/form-data' } })
const data = res.data as User
setUser (user => ({ ...user, ...data })) setUser (user => ({ ...user, ...data }))
toast ({ title: '設定を更新しました.' }) toast ({ title: '設定を更新しました.' })
} }
+3 -5
View File
@@ -1,12 +1,11 @@
import axios from 'axios'
import toCamel from 'camelcase-keys'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Helmet } from 'react-helmet-async' import { Helmet } from 'react-helmet-async'
import { useLocation, useParams } from 'react-router-dom' import { useLocation, useParams } from 'react-router-dom'
import PageTitle from '@/components/common/PageTitle' import PageTitle from '@/components/common/PageTitle'
import MainArea from '@/components/layout/MainArea' import MainArea from '@/components/layout/MainArea'
import { API_BASE_URL, SITE_TITLE } from '@/config' import { SITE_TITLE } from '@/config'
import { apiGet } from '@/lib/api'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import type { WikiPageDiff } from '@/types' import type { WikiPageDiff } from '@/types'
@@ -25,8 +24,7 @@ export default () => {
useEffect (() => { useEffect (() => {
void (async () => { void (async () => {
const res = await axios.get (`${ API_BASE_URL }/wiki/${ id }/diff`, { params: { from, to } }) setDiff (await apiGet<WikiPageDiff> (`/wiki/${ id }/diff`, { params: { from, to } }))
setDiff (toCamel (res.data as any, { deep: true }) as WikiPageDiff)
}) () }) ()
}, []) }, [])
+5 -7
View File
@@ -1,4 +1,3 @@
import axios from 'axios'
import MarkdownIt from 'markdown-it' import MarkdownIt from 'markdown-it'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Helmet } from 'react-helmet-async' import { Helmet } from 'react-helmet-async'
@@ -7,7 +6,8 @@ import { useParams, useNavigate } from 'react-router-dom'
import MainArea from '@/components/layout/MainArea' import MainArea from '@/components/layout/MainArea'
import { toast } from '@/components/ui/use-toast' import { toast } from '@/components/ui/use-toast'
import { API_BASE_URL, SITE_TITLE } from '@/config' import { SITE_TITLE } from '@/config'
import { apiGet, apiPut } from '@/lib/api'
import Forbidden from '@/pages/Forbidden' import Forbidden from '@/pages/Forbidden'
import 'react-markdown-editor-lite/lib/index.css' import 'react-markdown-editor-lite/lib/index.css'
@@ -40,9 +40,8 @@ export default (({ user }: Props) => {
try try
{ {
await axios.put (`${ API_BASE_URL }/wiki/${ id }`, formData, { headers: { await apiPut (`/wiki/${ id }`, formData,
'Content-Type': 'multipart/form-data', { headers: { 'Content-Type': 'multipart/form-data' } })
'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
toast ({ title: '投稿成功!' }) toast ({ title: '投稿成功!' })
navigate (`/wiki/${ title }`) navigate (`/wiki/${ title }`)
} }
@@ -55,8 +54,7 @@ export default (({ user }: Props) => {
useEffect (() => { useEffect (() => {
void (async () => { void (async () => {
setLoading (true) setLoading (true)
const res = await axios.get (`${ API_BASE_URL }/wiki/${ id }`) const data = await apiGet<WikiPage> (`/wiki/${ id }`)
const data = res.data as WikiPage
setTitle (data.title) setTitle (data.title)
setBody (data.body) setBody (data.body)
setLoading (false) setLoading (false)
+3 -6
View File
@@ -1,12 +1,11 @@
import axios from 'axios'
import toCamel from 'camelcase-keys'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Helmet } from 'react-helmet-async' import { Helmet } from 'react-helmet-async'
import { useLocation } from 'react-router-dom' import { useLocation } from 'react-router-dom'
import PrefetchLink from '@/components/PrefetchLink' import PrefetchLink from '@/components/PrefetchLink'
import MainArea from '@/components/layout/MainArea' import MainArea from '@/components/layout/MainArea'
import { API_BASE_URL, SITE_TITLE } from '@/config' import { SITE_TITLE } from '@/config'
import { apiGet } from '@/lib/api'
import type { WikiPageChange } from '@/types' import type { WikiPageChange } from '@/types'
@@ -20,9 +19,7 @@ export default () => {
useEffect (() => { useEffect (() => {
void (async () => { void (async () => {
const res = await axios.get (`${ API_BASE_URL }/wiki/changes`, setChanges (await apiGet<WikiPageChange[]> ('/wiki/changes', { params: id ? { id } : { } }))
{ params: { ...(id ? { id } : { }) } })
setChanges (toCamel (res.data as any, { deep: true }) as WikiPageChange[])
}) () }) ()
}, [location.search]) }, [location.search])