|
|
@@ -10,14 +10,14 @@ import { cn } from '@/lib/utils' |
|
|
|
|
|
|
|
import type { Tag, User, WikiPage } from '@/types' |
|
|
|
|
|
|
|
type Props = { user: User |
|
|
|
setUser: (user: User) => void } |
|
|
|
type Props = { user: User |
|
|
|
setUser: (user: User) => void } |
|
|
|
|
|
|
|
const enum Menu { None, |
|
|
|
Post, |
|
|
|
User, |
|
|
|
Tag, |
|
|
|
Wiki } |
|
|
|
Post, |
|
|
|
User, |
|
|
|
Tag, |
|
|
|
Wiki } |
|
|
|
|
|
|
|
|
|
|
|
const TopNav: React.FC = ({ user, setUser }: Props) => { |
|
|
@@ -35,14 +35,14 @@ const TopNav: React.FC = ({ user, setUser }: Props) => { |
|
|
|
const [postCount, setPostCount] = useState<number | null> (null) |
|
|
|
|
|
|
|
const MyLink = ({ to, title, menu, base }: { to: string |
|
|
|
title: string |
|
|
|
menu?: Menu |
|
|
|
base?: string }) => ( |
|
|
|
title: string |
|
|
|
menu?: Menu |
|
|
|
base?: string }) => ( |
|
|
|
<Link to={to} className={cn ('hover:text-orange-500 h-full flex items-center', |
|
|
|
(location.pathname.startsWith (base ?? to) |
|
|
|
? 'bg-gray-700 px-4 font-bold' |
|
|
|
: 'px-2'))}> |
|
|
|
{title} |
|
|
|
(location.pathname.startsWith (base ?? to) |
|
|
|
? 'bg-gray-700 px-4 font-bold' |
|
|
|
: 'px-2'))}> |
|
|
|
{title} |
|
|
|
</Link>) |
|
|
|
|
|
|
|
const whenTagSearchChanged = ev => { |
|
|
@@ -53,8 +53,8 @@ const TopNav: React.FC = ({ user, setUser }: Props) => { |
|
|
|
const q: string = ev.target.value.split (' ').at (-1) |
|
|
|
if (!(q)) |
|
|
|
{ |
|
|
|
setSuggestions ([]) |
|
|
|
return |
|
|
|
setSuggestions ([]) |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -66,8 +66,8 @@ const TopNav: React.FC = ({ user, setUser }: Props) => { |
|
|
|
const q: string = ev.target.value.split (' ').at (-1) |
|
|
|
if (!(q)) |
|
|
|
{ |
|
|
|
setSuggestions ([]) |
|
|
|
return |
|
|
|
setSuggestions ([]) |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -79,16 +79,16 @@ const TopNav: React.FC = ({ user, setUser }: Props) => { |
|
|
|
const q: string = ev.target.value.split (' ').at (-1) |
|
|
|
if (!(q)) |
|
|
|
{ |
|
|
|
setSuggestions ([]) |
|
|
|
return |
|
|
|
setSuggestions ([]) |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => { |
|
|
|
if (e.key === 'Enter' && wikiSearch.length && (!(suggestionsVsbl) || activeIndex < 0)) |
|
|
|
{ |
|
|
|
navigate (`/wiki/${ encodeURIComponent (wikiSearch) }`) |
|
|
|
setSuggestionsVsbl (false) |
|
|
|
navigate (`/wiki/${ encodeURIComponent (wikiSearch) }`) |
|
|
|
setSuggestionsVsbl (false) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -120,105 +120,113 @@ const TopNav: React.FC = ({ user, setUser }: Props) => { |
|
|
|
void ((async () => { |
|
|
|
try |
|
|
|
{ |
|
|
|
const { data: pageData } = await axios.get (`${ API_BASE_URL }/wiki/${ wikiId }`) |
|
|
|
const wikiPage: WikiPage = toCamel (pageData, { deep: true }) |
|
|
|
const { data: pageData } = await axios.get (`${ API_BASE_URL }/wiki/${ wikiId }`) |
|
|
|
const wikiPage: WikiPage = toCamel (pageData, { deep: true }) |
|
|
|
|
|
|
|
const { data: tagData } = await axios.get (`${ API_BASE_URL }/tags/name/${ wikiPage.title }`) |
|
|
|
const tag: Tag = toCamel (tagData, { deep: true }) |
|
|
|
const { data: tagData } = await axios.get (`${ API_BASE_URL }/tags/name/${ wikiPage.title }`) |
|
|
|
const tag: Tag = toCamel (tagData, { deep: true }) |
|
|
|
|
|
|
|
setPostCount (tag.postCount) |
|
|
|
setPostCount (tag.postCount) |
|
|
|
} |
|
|
|
catch |
|
|
|
{ |
|
|
|
setPostCount (0) |
|
|
|
setPostCount (0) |
|
|
|
} |
|
|
|
}) ()) |
|
|
|
}, [wikiId]) |
|
|
|
|
|
|
|
return ( |
|
|
|
<> |
|
|
|
<nav className="bg-gray-800 text-white px-3 flex justify-between items-center w-full min-h-[48px]"> |
|
|
|
<div className="flex items-center gap-2 h-full"> |
|
|
|
<Link to="/posts" className="mx-4 text-xl font-bold text-orange-500">ぼざクリ タグ広場</Link> |
|
|
|
<MyLink to="/posts" title="広場" /> |
|
|
|
<MyLink to="/tags" title="タグ" /> |
|
|
|
<MyLink to="/wiki/ヘルプ:ホーム" base="/wiki" title="Wiki" /> |
|
|
|
<MyLink to="/users" title="ニジラー" /> |
|
|
|
</div> |
|
|
|
<div className="ml-auto pr-4"> |
|
|
|
<Button onClick={() => navigate ('/users/settings')}>{user?.name || '名もなきニジラー'}</Button> |
|
|
|
</div> |
|
|
|
</nav> |
|
|
|
{(() => { |
|
|
|
const className = 'bg-gray-700 text-white px-3 flex items-center w-full min-h-[40px]' |
|
|
|
const subClass = 'hover:text-orange-500 h-full flex items-center px-3' |
|
|
|
const inputBox = 'flex items-center px-3 mx-2' |
|
|
|
const Separator = () => <span className="flex items-center px-2">|</span> |
|
|
|
switch (selectedMenu) |
|
|
|
{ |
|
|
|
case Menu.Post: |
|
|
|
return ( |
|
|
|
<div className={className}> |
|
|
|
<Link to="/posts" className={subClass}>一覧</Link> |
|
|
|
<Link to="/posts/new" className={subClass}>投稿追加</Link> |
|
|
|
<Link to="/wiki/ヘルプ:広場" className={subClass}>ヘルプ</Link> |
|
|
|
</div>) |
|
|
|
case Menu.Tag: |
|
|
|
return ( |
|
|
|
<div className={className}> |
|
|
|
<input type="text" |
|
|
|
className={inputBox} |
|
|
|
placeholder="タグ検索" |
|
|
|
value={tagSearch} |
|
|
|
onChange={whenTagSearchChanged} |
|
|
|
onFocus={() => setSuggestionsVsbl (true)} |
|
|
|
onBlur={() => setSuggestionsVsbl (false)} |
|
|
|
onKeyDown={handleKeyDown} /> |
|
|
|
<Link to="/tags" className={subClass}>タグ</Link> |
|
|
|
<Link to="/tags/aliases" className={subClass}>別名タグ</Link> |
|
|
|
<Link to="/tags/implications" className={subClass}>上位タグ</Link> |
|
|
|
<Link to="/wiki/ヘルプ:タグのつけ方" className={subClass}>タグのつけ方</Link> |
|
|
|
<Link to="/wiki/ヘルプ:タグ" className={subClass}>ヘルプ</Link> |
|
|
|
</div>) |
|
|
|
case Menu.Wiki: |
|
|
|
return ( |
|
|
|
<div className={className}> |
|
|
|
<input type="text" |
|
|
|
className={inputBox} |
|
|
|
placeholder="Wiki 検索" |
|
|
|
value={wikiSearch} |
|
|
|
onChange={whenWikiSearchChanged} |
|
|
|
onFocus={() => setSuggestionsVsbl (true)} |
|
|
|
onBlur={() => setSuggestionsVsbl (false)} |
|
|
|
onKeyDown={handleKeyDown} /> |
|
|
|
<Link to="/wiki" className={subClass}>検索</Link> |
|
|
|
<Link to="/wiki/new" className={subClass}>新規</Link> |
|
|
|
<Link to="/wiki/changes" className={subClass}>全体履歴</Link> |
|
|
|
<Link to="/wiki/ヘルプ:Wiki" className={subClass}>ヘルプ</Link> |
|
|
|
{(/^\/wiki\/(?!new|changes)[^\/]+/.test (location.pathname) && wikiId) && |
|
|
|
<> |
|
|
|
<Separator /> |
|
|
|
<Link to={`/posts?tags=${ location.pathname.split ('/')[2] }`} className={subClass}>広場 ({postCount || 0})</Link> |
|
|
|
<Link to={`/wiki/changes?id=${ wikiId }`} className={subClass}>履歴</Link> |
|
|
|
<Link to={`/wiki/${ wikiId || location.pathname.split ('/')[2] }/edit`} className={subClass}>編輯</Link> |
|
|
|
</>} |
|
|
|
</div>) |
|
|
|
case Menu.User: |
|
|
|
return ( |
|
|
|
<div className={className}> |
|
|
|
<input type="text" |
|
|
|
className={inputBox} |
|
|
|
placeholder="ニジラー検索" |
|
|
|
value={userSearch} |
|
|
|
onChange={whenUserSearchChanged} |
|
|
|
onFocus={() => setSuggestionsVsbl (true)} |
|
|
|
onBlur={() => setSuggestionsVsbl (false)} |
|
|
|
onKeyDown={handleKeyDown} /> |
|
|
|
<Link to="/users" className={subClass}>一覧</Link> |
|
|
|
{user && <Link to={`/users/${ user.id }`} className={subClass}>お前</Link>} |
|
|
|
</div>) |
|
|
|
} |
|
|
|
}) ()} |
|
|
|
<nav className="bg-gray-800 text-white px-3 flex justify-between items-center w-full min-h-[48px]"> |
|
|
|
<div className="flex items-center gap-2 h-full"> |
|
|
|
<Link to="/posts" className="mx-4 text-xl font-bold text-orange-500">ぼざクリ タグ広場</Link> |
|
|
|
<MyLink to="/posts" title="広場" /> |
|
|
|
<MyLink to="/tags" title="タグ" /> |
|
|
|
<MyLink to="/wiki/ヘルプ:ホーム" base="/wiki" title="Wiki" /> |
|
|
|
<MyLink to="/users/settings" base="/users" title="ニジラー" /> |
|
|
|
</div> |
|
|
|
<div className="ml-auto pr-4"> |
|
|
|
{user && ( |
|
|
|
<Button onClick={() => navigate ('/users/settings')} |
|
|
|
className="bg-gray-600"> |
|
|
|
{user.name || '名もなきニジラー'} |
|
|
|
</Button>)} |
|
|
|
</div> |
|
|
|
</nav> |
|
|
|
{(() => { |
|
|
|
const className = 'bg-gray-700 text-white px-3 flex items-center w-full min-h-[40px]' |
|
|
|
const subClass = 'hover:text-orange-500 h-full flex items-center px-3' |
|
|
|
const inputBox = 'flex items-center px-3 mx-2' |
|
|
|
const Separator = () => <span className="flex items-center px-2">|</span> |
|
|
|
switch (selectedMenu) |
|
|
|
{ |
|
|
|
case Menu.Post: |
|
|
|
return ( |
|
|
|
<div className={className}> |
|
|
|
<Link to="/posts" className={subClass}>一覧</Link> |
|
|
|
<Link to="/posts/new" className={subClass}>投稿追加</Link> |
|
|
|
<Link to="/wiki/ヘルプ:広場" className={subClass}>ヘルプ</Link> |
|
|
|
</div>) |
|
|
|
case Menu.Tag: |
|
|
|
return ( |
|
|
|
<div className={className}> |
|
|
|
{/* TODO: リリース後にやる */} |
|
|
|
{/* <input type="text" |
|
|
|
className={inputBox} |
|
|
|
placeholder="タグ検索" |
|
|
|
value={tagSearch} |
|
|
|
onChange={whenTagSearchChanged} |
|
|
|
onFocus={() => setSuggestionsVsbl (true)} |
|
|
|
onBlur={() => setSuggestionsVsbl (false)} |
|
|
|
onKeyDown={handleKeyDown} /> */} |
|
|
|
<Link to="/tags" className={subClass}>タグ</Link> |
|
|
|
<Link to="/tags/aliases" className={subClass}>別名タグ</Link> |
|
|
|
<Link to="/tags/implications" className={subClass}>上位タグ</Link> |
|
|
|
<Link to="/wiki/ヘルプ:タグのつけ方" className={subClass}>タグのつけ方</Link> |
|
|
|
<Link to="/wiki/ヘルプ:タグ" className={subClass}>ヘルプ</Link> |
|
|
|
</div>) |
|
|
|
case Menu.Wiki: |
|
|
|
return ( |
|
|
|
<div className={className}> |
|
|
|
{/* TODO: リリース後にやる */} |
|
|
|
{/* <input type="text" |
|
|
|
className={inputBox} |
|
|
|
placeholder="Wiki 検索" |
|
|
|
value={wikiSearch} |
|
|
|
onChange={whenWikiSearchChanged} |
|
|
|
onFocus={() => setSuggestionsVsbl (true)} |
|
|
|
onBlur={() => setSuggestionsVsbl (false)} |
|
|
|
onKeyDown={handleKeyDown} /> */} |
|
|
|
<Link to="/wiki" className={subClass}>検索</Link> |
|
|
|
<Link to="/wiki/new" className={subClass}>新規</Link> |
|
|
|
<Link to="/wiki/changes" className={subClass}>全体履歴</Link> |
|
|
|
<Link to="/wiki/ヘルプ:Wiki" className={subClass}>ヘルプ</Link> |
|
|
|
{(/^\/wiki\/(?!new|changes)[^\/]+/.test (location.pathname) && wikiId) && |
|
|
|
<> |
|
|
|
<Separator /> |
|
|
|
<Link to={`/posts?tags=${ location.pathname.split ('/')[2] }`} className={subClass}>広場 ({postCount || 0})</Link> |
|
|
|
<Link to={`/wiki/changes?id=${ wikiId }`} className={subClass}>履歴</Link> |
|
|
|
<Link to={`/wiki/${ wikiId || location.pathname.split ('/')[2] }/edit`} className={subClass}>編輯</Link> |
|
|
|
</>} |
|
|
|
</div>) |
|
|
|
case Menu.User: |
|
|
|
return ( |
|
|
|
<div className={className}> |
|
|
|
{/* TODO: リリース後にやる */} |
|
|
|
{/* <input type="text" |
|
|
|
className={inputBox} |
|
|
|
placeholder="ニジラー検索" |
|
|
|
value={userSearch} |
|
|
|
onChange={whenUserSearchChanged} |
|
|
|
onFocus={() => setSuggestionsVsbl (true)} |
|
|
|
onBlur={() => setSuggestionsVsbl (false)} |
|
|
|
onKeyDown={handleKeyDown} /> */} |
|
|
|
{/* <Link to="/users" className={subClass}>一覧</Link> |
|
|
|
{user && <Link to={`/users/${ user.id }`} className={subClass}>お前</Link>} */} |
|
|
|
{user && <Link to="/users/settings" className={subClass}>設定</Link>} |
|
|
|
</div>) |
|
|
|
} |
|
|
|
}) ()} |
|
|
|
</>) |
|
|
|
} |
|
|
|
|
|
|
|