@@ -34,7 +34,7 @@ export default ({ post, onSave }: Props) => { | |||||
}, []) | }, []) | ||||
return ( | return ( | ||||
<div className="max-w-xl p-4 space-y-4"> | |||||
<div className="max-w-xl pt-2 space-y-4"> | |||||
{/* タイトル */} | {/* タイトル */} | ||||
<div> | <div> | ||||
<div className="flex gap-2 mb-1"> | <div className="flex gap-2 mb-1"> | ||||
@@ -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>) | |||||
} |
@@ -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>) | |||||
} |
@@ -10,7 +10,7 @@ import { cn } from '@/lib/utils' | |||||
import MainArea from '@/components/layout/MainArea' | import MainArea from '@/components/layout/MainArea' | ||||
import TagDetailSidebar from '@/components/TagDetailSidebar' | import TagDetailSidebar from '@/components/TagDetailSidebar' | ||||
import PostEditForm from '@/components/PostEditForm' | 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' | 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 ? 'bg-blue-600 hover:bg-blue-700' : 'bg-gray-500 hover:bg-gray-600')}> | ||||
{post.viewed ? '閲覧済' : '未閲覧'} | {post.viewed ? '閲覧済' : '未閲覧'} | ||||
</Button> | </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>) | </div>) | ||||
: 'Loading...'} | : 'Loading...'} | ||||
</MainArea> | </MainArea> | ||||