Browse Source

#49 TabGroup 作成

main
みてるぞ 3 weeks ago
parent
commit
ba1c1f1adf
4 changed files with 50 additions and 35 deletions
  1. +1
    -1
      frontend/src/components/PostEditForm.tsx
  2. +0
    -25
      frontend/src/components/common/TabControl.tsx
  3. +38
    -0
      frontend/src/components/common/TabGroup.tsx
  4. +11
    -9
      frontend/src/pages/PostDetailPage.tsx

+ 1
- 1
frontend/src/components/PostEditForm.tsx View File

@@ -34,7 +34,7 @@ export default ({ post, onSave }: Props) => {
}, [])

return (
<div className="max-w-xl p-4 space-y-4">
<div className="max-w-xl pt-2 space-y-4">
{/* タイトル */}
<div>
<div className="flex gap-2 mb-1">


+ 0
- 25
frontend/src/components/common/TabControl.tsx View File

@@ -1,25 +0,0 @@
import React, { useEffect, useState } from 'react'

type Props = { tabs: { [key: string]: React.ReactNode }
init?: string }


export default ({ tabs, init }: Props) => {
const [current, setCurrent] = useState<string> (init
?? Object.keys (tabs)?.[0]
?? '')

return (
<div className="mt-4">
{Object.entries (tabs).map (([name, element]) => (
<a href="#"
className="text-blue-400 hover:underline cursor-pointer"
onClick={(event) => {
event.preventDefault ()
setCurrent (name)
}}>
{name}
</a>))}
{current && tabs[current]}
</div>)
}

+ 38
- 0
frontend/src/components/common/TabGroup.tsx View File

@@ -0,0 +1,38 @@
import React, { useState } from 'react'

type TabProps = { name: string
init?: boolean
children: React.ReactNode }

type Props = { children: React.ReactElement<{ name: string }>[] }

export const Tab = ({ children }: TabProps) => children


export default ({ children }: Props) => {
const tabs = React.Children.toArray (children)

const [current, setCurrent] = useState<number> (() => {
const i = tabs.findIndex (tab => tab.props.init)
return i >= 0 ? i : 0
})

return (
<div className="mt-4">
<div className="flex gap-4">
{tabs.map ((tab, i) => (
<a key={i}
href="#"
className={`text-blue-400 hover:underline ${ i === current ? 'font-bold' : '' }`}
onClick={ev => {
ev.preventDefault ()
setCurrent (i)
}}>
{tab.props.name}
</a>))}
</div>
<div className="mt-2">
{tabs[current]}
</div>
</div>)
}

+ 11
- 9
frontend/src/pages/PostDetailPage.tsx View File

@@ -10,7 +10,7 @@ import { cn } from '@/lib/utils'
import MainArea from '@/components/layout/MainArea'
import TagDetailSidebar from '@/components/TagDetailSidebar'
import PostEditForm from '@/components/PostEditForm'
import TabControl from '@/components/common/TabControl'
import TabGroup, { Tab } from '@/components/common/TabGroup'

import type { Post, Tag, User } from '@/types'

@@ -95,14 +95,16 @@ export default ({ user }: Props) => {
post.viewed ? 'bg-blue-600 hover:bg-blue-700' : 'bg-gray-500 hover:bg-gray-600')}>
{post.viewed ? '閲覧済' : '未閲覧'}
</Button>
{(['admin', 'member'].includes (user.role) && editing) &&
<TabControl tabs={{
['編輯']: (
<PostEditForm post={post}
onSave={newPost => {
setPost (newPost)
toast ({ description: '更新しました.' })
}} />) }} />}
<TabGroup>
{['admin', 'member'].some (r => r === user.role) && editing &&
<Tab name="編輯">
<PostEditForm post={post}
onSave={newPost => {
setPost (newPost)
toast ({ description: '更新しました.' })
}} />
</Tab>}
</TabGroup>
</div>)
: 'Loading...'}
</MainArea>


Loading…
Cancel
Save