このコミットが含まれているのは:
@@ -1,11 +1,9 @@
|
||||
import axios from 'axios'
|
||||
import toCamel from 'camelcase-keys'
|
||||
import { useRef, useState } from 'react'
|
||||
|
||||
import TagSearchBox from '@/components/TagSearchBox'
|
||||
import Label from '@/components/common/Label'
|
||||
import TextArea from '@/components/common/TextArea'
|
||||
import { API_BASE_URL } from '@/config'
|
||||
import { apiGet } from '@/lib/api'
|
||||
|
||||
import type { FC, SyntheticEvent } from 'react'
|
||||
|
||||
@@ -59,8 +57,7 @@ export default (({ tags, setTags }: Props) => {
|
||||
const recompute = async (pos: number, v: string = tags) => {
|
||||
const { start, end, token } = getTokenAt (v, pos)
|
||||
setBounds ({ start, end })
|
||||
const res = await axios.get (`${ API_BASE_URL }/tags/autocomplete`, { params: { q: token } })
|
||||
const data = toCamel (res.data as any, { deep: true }) as Tag[]
|
||||
const data = await apiGet<Tag[]> ('/tags/autocomplete', { params: { q: token } })
|
||||
setSuggestions (data.filter (t => t.postCount > 0))
|
||||
setSuggestionsVsbl (suggestions.length > 0)
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ import { DndContext,
|
||||
useSensor,
|
||||
useSensors } from '@dnd-kit/core'
|
||||
import { restrictToWindowEdges } from '@dnd-kit/modifiers'
|
||||
import axios from 'axios'
|
||||
import toCamel from 'camelcase-keys'
|
||||
import { AnimatePresence, motion } from 'framer-motion'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
@@ -19,8 +17,8 @@ import SectionTitle from '@/components/common/SectionTitle'
|
||||
import SubsectionTitle from '@/components/common/SubsectionTitle'
|
||||
import SidebarComponent from '@/components/layout/SidebarComponent'
|
||||
import { toast } from '@/components/ui/use-toast'
|
||||
import { API_BASE_URL } from '@/config'
|
||||
import { CATEGORIES } from '@/consts'
|
||||
import { apiDelete, apiGet, apiPatch, apiPost } from '@/lib/api'
|
||||
|
||||
import type { DragEndEvent } from '@dnd-kit/core'
|
||||
import type { FC, MutableRefObject, ReactNode } from 'react'
|
||||
@@ -132,10 +130,7 @@ const changeCategory = async (
|
||||
tagId: number,
|
||||
category: Category,
|
||||
): Promise<void> => {
|
||||
await axios.patch (
|
||||
`${ API_BASE_URL }/tags/${ tagId }`,
|
||||
{ category },
|
||||
{ headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
|
||||
await apiPatch (`/tags/${ tagId }`, { category })
|
||||
}
|
||||
|
||||
|
||||
@@ -170,12 +165,7 @@ export default (({ post }: Props) => {
|
||||
if (!(post))
|
||||
return
|
||||
|
||||
const res = await axios.get (
|
||||
`${ 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))
|
||||
setTags (buildTagByCategory (await apiGet<Post> (`/posts/${ post.id }`)))
|
||||
}
|
||||
|
||||
const onDragEnd = async (e: DragEndEvent) => {
|
||||
@@ -216,16 +206,9 @@ export default (({ post }: Props) => {
|
||||
return
|
||||
|
||||
if (fromParentId != null)
|
||||
{
|
||||
await axios.delete (
|
||||
`${ API_BASE_URL }/tags/${ fromParentId }/children/${ childId }`,
|
||||
{ headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
|
||||
}
|
||||
await apiDelete (`/tags/${ fromParentId }/children/${ childId }`)
|
||||
|
||||
await axios.post (
|
||||
`${ API_BASE_URL }/tags/${ parentId }/children/${ childId }`,
|
||||
{ },
|
||||
{ headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
|
||||
await apiPost (`/tags/${ parentId }/children/${ childId }`, { })
|
||||
|
||||
await reloadTags ()
|
||||
toast ({
|
||||
@@ -245,11 +228,7 @@ export default (({ post }: Props) => {
|
||||
await changeCategory (childId, cat)
|
||||
|
||||
if (fromParentId != null)
|
||||
{
|
||||
await axios.delete (
|
||||
`${ API_BASE_URL }/tags/${ fromParentId }/children/${ childId }`,
|
||||
{ headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
|
||||
}
|
||||
await apiDelete (`/tags/${ fromParentId }/children/${ childId }`)
|
||||
|
||||
const fromParent = fromParentId == null ? null : findTag (tags, fromParentId)
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import axios from 'axios'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import PrefetchLink from '@/components/PrefetchLink'
|
||||
import { API_BASE_URL } from '@/config'
|
||||
import { LIGHT_COLOUR_SHADE, DARK_COLOUR_SHADE, TAG_COLOUR } from '@/consts'
|
||||
import { apiGet } from '@/lib/api'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
import type { ComponentProps, FC, HTMLAttributes } from 'react'
|
||||
|
||||
import type { Tag } from '@/types'
|
||||
|
||||
type CommonProps = { tag: Tag
|
||||
nestLevel?: number
|
||||
withWiki?: boolean
|
||||
withCount?: boolean
|
||||
prefetch?: boolean }
|
||||
type CommonProps = {
|
||||
tag: Tag
|
||||
nestLevel?: number
|
||||
withWiki?: boolean
|
||||
withCount?: boolean
|
||||
prefetch?: boolean }
|
||||
|
||||
type PropsWithLink =
|
||||
& CommonProps
|
||||
@@ -26,7 +26,9 @@ type PropsWithoutLink =
|
||||
& { linkFlg: false }
|
||||
& Partial<HTMLAttributes<HTMLSpanElement>>
|
||||
|
||||
type Props = PropsWithLink | PropsWithoutLink
|
||||
type Props =
|
||||
| PropsWithLink
|
||||
| PropsWithoutLink
|
||||
|
||||
|
||||
export default (({ tag,
|
||||
@@ -49,7 +51,7 @@ export default (({ tag,
|
||||
|
||||
try
|
||||
{
|
||||
await axios.get (`${ API_BASE_URL }/wiki/title/${ encodeURIComponent (tagName) }/exists`)
|
||||
await apiGet (`/wiki/title/${ encodeURIComponent (tagName) }/exists`)
|
||||
setHavingWiki (true)
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import axios from 'axios'
|
||||
import toCamel from 'camelcase-keys'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useNavigate, useLocation } from 'react-router-dom'
|
||||
|
||||
import { API_BASE_URL } from '@/config'
|
||||
import { apiGet } from '@/lib/api'
|
||||
|
||||
import TagSearchBox from './TagSearchBox'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { ChangeEvent, FC, KeyboardEvent } from 'react'
|
||||
|
||||
import type { Tag } from '@/types'
|
||||
|
||||
@@ -21,7 +19,7 @@ export default (() => {
|
||||
const [suggestions, setSuggestions] = useState<Tag[]> ([])
|
||||
const [suggestionsVsbl, setSuggestionsVsbl] = useState (false)
|
||||
|
||||
const whenChanged = async (ev: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const whenChanged = async (ev: ChangeEvent<HTMLInputElement>) => {
|
||||
setSearch (ev.target.value)
|
||||
|
||||
const q = ev.target.value.trim ().split (' ').at (-1)
|
||||
@@ -31,14 +29,13 @@ export default (() => {
|
||||
return
|
||||
}
|
||||
|
||||
const res = await axios.get (`${ API_BASE_URL }/tags/autocomplete`, { params: { q } })
|
||||
const data = toCamel (res.data, { deep: true }) as Tag[]
|
||||
const data = await apiGet<Tag[]> ('/tags/autocomplete', { params: { q } })
|
||||
setSuggestions (data.filter (t => t.postCount > 0))
|
||||
if (suggestions.length > 0)
|
||||
setSuggestionsVsbl (true)
|
||||
}
|
||||
|
||||
const handleKeyDown = (ev: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
const handleKeyDown = (ev: KeyboardEvent<HTMLInputElement>) => {
|
||||
switch (ev.key)
|
||||
{
|
||||
case 'ArrowDown':
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import axios from 'axios'
|
||||
import { AnimatePresence, motion } from 'framer-motion'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
@@ -7,8 +6,8 @@ import TagLink from '@/components/TagLink'
|
||||
import TagSearch from '@/components/TagSearch'
|
||||
import SectionTitle from '@/components/common/SectionTitle'
|
||||
import SidebarComponent from '@/components/layout/SidebarComponent'
|
||||
import { API_BASE_URL } from '@/config'
|
||||
import { CATEGORIES } from '@/consts'
|
||||
import { apiGet } from '@/lib/api'
|
||||
|
||||
import type { FC, MouseEvent } from 'react'
|
||||
|
||||
@@ -77,10 +76,10 @@ export default (({ posts, onClick }: Props) => {
|
||||
void ((async () => {
|
||||
try
|
||||
{
|
||||
const { data } = await axios.get (`${ API_BASE_URL }/posts/random`,
|
||||
{ params: { tags: tagsQuery.split (' ').filter (e => e !== '').join (' '),
|
||||
const data = await apiGet<Post> ('/posts/random',
|
||||
{ params: { tags: tagsQuery.split (' ').filter (e => e !== '').join (' '),
|
||||
match: (anyFlg ? 'any' : 'all') } })
|
||||
navigate (`/posts/${ (data as Post).id }`)
|
||||
navigate (`/posts/${ data.id }`)
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import axios from 'axios'
|
||||
import toCamel from 'camelcase-keys'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import ReactMarkdown from 'react-markdown'
|
||||
import remarkGFM from 'remark-gfm'
|
||||
@@ -7,7 +5,7 @@ import remarkGFM from 'remark-gfm'
|
||||
import PrefetchLink from '@/components/PrefetchLink'
|
||||
import SectionTitle from '@/components/common/SectionTitle'
|
||||
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 type { FC } from 'react'
|
||||
@@ -43,8 +41,7 @@ export default (({ title, body }: Props) => {
|
||||
void (async () => {
|
||||
try
|
||||
{
|
||||
const res = await axios.get (`${ API_BASE_URL }/wiki`)
|
||||
const data: WikiPage[] = toCamel (res.data as any, { deep: true })
|
||||
const data = await apiGet<WikiPage[]> ('/wiki')
|
||||
setPageNames (data.map (page => page.title).sort ((a, b) => b.length - a.length))
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import axios from 'axios'
|
||||
import toCamel from 'camelcase-keys'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { Button } from '@/components/ui/button'
|
||||
@@ -8,7 +6,7 @@ import { Dialog,
|
||||
DialogTitle } from '@/components/ui/dialog'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { toast } from '@/components/ui/use-toast'
|
||||
import { API_BASE_URL } from '@/config'
|
||||
import { apiPost } from '@/lib/api'
|
||||
|
||||
import type { User } from '@/types'
|
||||
|
||||
@@ -26,12 +24,12 @@ export default ({ visible, onVisibleChange, setUser }: Props) => {
|
||||
|
||||
try
|
||||
{
|
||||
const res = await axios.post (`${ API_BASE_URL }/users/verify`, { code: inputCode })
|
||||
const data = res.data as { valid: boolean; user: any }
|
||||
const data = await apiPost<{ valid: boolean; user: User }> (
|
||||
'/users/verify', { code: inputCode })
|
||||
if (data.valid)
|
||||
{
|
||||
localStorage.setItem ('user_code', inputCode)
|
||||
setUser (toCamel (data.user, { deep: true }))
|
||||
setUser (data.user)
|
||||
toast ({ title: '引継ぎ成功!' })
|
||||
onVisibleChange (false)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import axios from 'axios'
|
||||
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Dialog,
|
||||
DialogContent,
|
||||
DialogTitle } from '@/components/ui/dialog'
|
||||
import { toast } from '@/components/ui/use-toast'
|
||||
import { API_BASE_URL } from '@/config'
|
||||
import { apiPost } from '@/lib/api'
|
||||
|
||||
import type { User } from '@/types'
|
||||
|
||||
@@ -23,10 +21,8 @@ export default ({ visible, onVisibleChange, user, setUser }: Props) => {
|
||||
if (!(confirm ('引継ぎコードを再発行しますか?\n再発行するとほかのブラウザからはログアウトされます.')))
|
||||
return
|
||||
|
||||
const res = await axios.post (`${ API_BASE_URL }/users/code/renew`, { }, { headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
'X-Transfer-Code': localStorage.getItem ('user_code') || '' } })
|
||||
const data = res.data as { code: string }
|
||||
const data = await apiPost<{ code: string }> ('/users/code/renew', { },
|
||||
{ headers: { 'Content-Type': 'multipart/form-data' } })
|
||||
if (data.code)
|
||||
{
|
||||
localStorage.setItem ('user_code', data.code)
|
||||
|
||||
新しい課題から参照
ユーザをブロックする