✨ frontend add
This commit is contained in:
19
frontend/portal/src/hooks/useInputs.ts
Normal file
19
frontend/portal/src/hooks/useInputs.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import React, { useState } from 'react'
|
||||
|
||||
export default function useInputs(initial: ValueType) {
|
||||
const [value, setValue] = useState<ValueType>(initial)
|
||||
|
||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setValue(event.target.value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @TODO
|
||||
* validation 추가필요
|
||||
*/
|
||||
|
||||
return {
|
||||
value,
|
||||
onChange: handleChange,
|
||||
}
|
||||
}
|
||||
25
frontend/portal/src/hooks/useLocalStorage.ts
Normal file
25
frontend/portal/src/hooks/useLocalStorage.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { useState } from 'react'
|
||||
|
||||
export const useLocalStorage = (key: string, initialValue: unknown = '') => {
|
||||
const [storeValue, setStoreValue] = useState(() => {
|
||||
try {
|
||||
const item = window.localStorage.getItem(key)
|
||||
return item ? JSON.parse(item) : initialValue
|
||||
} catch (error) {
|
||||
return initialValue
|
||||
}
|
||||
})
|
||||
|
||||
const setValue = (value: unknown) => {
|
||||
try {
|
||||
const valueToStore = value instanceof Function ? value(storeValue) : value
|
||||
|
||||
setStoreValue(valueToStore)
|
||||
window.localStorage.setItem(key, JSON.stringify(valueToStore))
|
||||
} catch (error) {
|
||||
console.error(`useLocalStorage setValue error : ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
return [storeValue, setValue]
|
||||
}
|
||||
11
frontend/portal/src/hooks/useMounted.ts
Normal file
11
frontend/portal/src/hooks/useMounted.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
export default function useMounted() {
|
||||
const [mounted, setMounted] = useState<boolean>(false)
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true)
|
||||
}, [])
|
||||
|
||||
return mounted
|
||||
}
|
||||
17
frontend/portal/src/hooks/usePage.ts
Normal file
17
frontend/portal/src/hooks/usePage.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { pageAtom, pageSelector } from '@stores'
|
||||
import { useState } from 'react'
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil'
|
||||
|
||||
export default function usePage(conditionKey: string, initPage: number = 0) {
|
||||
const pageState = useRecoilValue(pageAtom(conditionKey))
|
||||
const setValue = useSetRecoilState(pageSelector(conditionKey))
|
||||
|
||||
const [page, setPage] = useState<number>(pageState || initPage)
|
||||
|
||||
const setPageValue = (num: number) => {
|
||||
setValue(num)
|
||||
setPage(num)
|
||||
}
|
||||
|
||||
return { page, setPageValue }
|
||||
}
|
||||
12
frontend/portal/src/hooks/useSearchTypes.ts
Normal file
12
frontend/portal/src/hooks/useSearchTypes.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { OptionsType } from '@components/Inputs'
|
||||
|
||||
export default function useSearchTypes(init: OptionsType[]) {
|
||||
const [searchTypes, setSearchTypes] = useState<OptionsType[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
setSearchTypes(init)
|
||||
}, [])
|
||||
|
||||
return searchTypes
|
||||
}
|
||||
53
frontend/portal/src/hooks/useTextarea.ts
Normal file
53
frontend/portal/src/hooks/useTextarea.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { COMMENTS_MAX_LENGTH } from '@constants'
|
||||
import { getTextLength } from '@utils'
|
||||
import React, { useState } from 'react'
|
||||
|
||||
export interface ITextarea {
|
||||
value: ValueType | ReadonlyArray<string>
|
||||
currentCount: number
|
||||
}
|
||||
|
||||
export default function useTextarea(
|
||||
initial: ITextarea,
|
||||
maxLength: number = COMMENTS_MAX_LENGTH,
|
||||
) {
|
||||
const [textarea, setTextarea] = useState<ITextarea>(initial)
|
||||
const max = maxLength
|
||||
|
||||
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
let targetValue = event.target.value
|
||||
const count = getTextLength(targetValue)
|
||||
if (count > max) {
|
||||
setTextarea({
|
||||
value: targetValue.slice(0, max),
|
||||
currentCount: max,
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
setTextarea({
|
||||
value: targetValue,
|
||||
currentCount: count,
|
||||
})
|
||||
}
|
||||
|
||||
const clearTextarea = () => {
|
||||
setTextarea({
|
||||
value: '',
|
||||
currentCount: 0,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @TODO
|
||||
* validation 추가필요
|
||||
*/
|
||||
|
||||
return {
|
||||
currentCount: textarea.currentCount,
|
||||
clear: clearTextarea,
|
||||
value: textarea.value,
|
||||
onChange: handleChange,
|
||||
}
|
||||
}
|
||||
49
frontend/portal/src/hooks/useUser.ts
Normal file
49
frontend/portal/src/hooks/useUser.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { useEffect } from 'react'
|
||||
import useSWR from 'swr'
|
||||
import axios from 'axios'
|
||||
import { AUTH_USER_ID } from '@constants/env'
|
||||
import { loginSerivce } from '@service'
|
||||
import { userAtom } from '@stores'
|
||||
import { useSetRecoilState } from 'recoil'
|
||||
|
||||
export default function useUser() {
|
||||
const { data, error, mutate } = useSWR(
|
||||
`/user-service/api/v1/users`,
|
||||
async (url: string) => {
|
||||
let userId = axios.defaults.headers.common[AUTH_USER_ID]
|
||||
if (!userId) {
|
||||
await loginSerivce.silentRefresh()
|
||||
}
|
||||
userId = axios.defaults.headers.common[AUTH_USER_ID]
|
||||
if (userId) {
|
||||
return axios.get(`${url}/${userId}`).then(res => res.data)
|
||||
} else {
|
||||
throw new Error('No User')
|
||||
}
|
||||
},
|
||||
{
|
||||
shouldRetryOnError: false,
|
||||
},
|
||||
)
|
||||
|
||||
const setUser = useSetRecoilState(userAtom)
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setUser(data)
|
||||
}
|
||||
}, [data])
|
||||
|
||||
const loading = !data && !error
|
||||
const isLogin = !Boolean(error) && Boolean(data)
|
||||
const loggedOut =
|
||||
error && (error.response?.status === 401 || error.response?.status === 403)
|
||||
|
||||
return {
|
||||
user: data,
|
||||
loading,
|
||||
isLogin,
|
||||
error,
|
||||
mutate,
|
||||
loggedOut,
|
||||
}
|
||||
}
|
||||
35
frontend/portal/src/hooks/useWindowSize.ts
Normal file
35
frontend/portal/src/hooks/useWindowSize.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
export default function useWindowSize() {
|
||||
const [windowSize, setWindowSize] = useState<{
|
||||
width: number
|
||||
height: number
|
||||
}>({
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
// only execute all the code below in client side
|
||||
if (typeof window !== 'undefined') {
|
||||
// Handler to call on window resize
|
||||
function handleResize() {
|
||||
// Set window width/height to state
|
||||
setWindowSize({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
})
|
||||
}
|
||||
|
||||
// Add event listener
|
||||
window.addEventListener('resize', handleResize)
|
||||
|
||||
// Call handler right away so state gets updated with initial window size
|
||||
handleResize()
|
||||
|
||||
// Remove event listener on cleanup
|
||||
return () => window.removeEventListener('resize', handleResize)
|
||||
}
|
||||
}, []) // Empty array ensures that effect is only run on mount
|
||||
return windowSize
|
||||
}
|
||||
Reference in New Issue
Block a user