diff --git a/backend/app/controllers/wiki_pages_controller.rb b/backend/app/controllers/wiki_pages_controller.rb index 47a388a..c792fb7 100644 --- a/backend/app/controllers/wiki_pages_controller.rb +++ b/backend/app/controllers/wiki_pages_controller.rb @@ -66,14 +66,14 @@ class WikiPagesController < ApplicationController end def search - q = WikiPage.all + title = params[:title]&.strip - if params[:title].present? - title = params[:title].to_s.strip - q = q.where('title LIKE ?', "%#{ WikiPage.sanitize_sql_like(title) }%") - end + q = WikiPage.all + q = q.where('title LIKE ?', "%#{ WikiPage.sanitize_sql_like(title) }%") if title.present? - render json: q.limit(20) + render json: q.limit(20).map { |page| + page.sha = nil + page } end def changes diff --git a/frontend/src/components/TopNav.tsx b/frontend/src/components/TopNav.tsx index 1598e0f..3da0091 100644 --- a/frontend/src/components/TopNav.tsx +++ b/frontend/src/components/TopNav.tsx @@ -12,7 +12,7 @@ type Props = { user: User const enum Menu { None, Post, - Deerjikist, + User, Tag, Wiki } @@ -28,6 +28,8 @@ const TopNav: React.FC = ({ user, setUser }: Props) => { const [activeIndex, setActiveIndex] = useState (-1) const [suggestions, setSuggestions] = useState ([]) const [suggestionsVsbl, setSuggestionsVsbl] = useState (false) + const [tagSearch, setTagSearch] = useState ('') + const [userSearch, setUserSearch] = useState ('') const MyLink = ({ to, title, menu, base }: { to: string title: string @@ -40,16 +42,43 @@ const TopNav: React.FC = ({ user, setUser }: Props) => { {title} ) - const whenWikiSearchChanged = e => { - setWikiSearch (e.target.value) + const whenTagSearchChanged = ev => { + // TODO: 実装 - const q: string = e.target.value.split (' ').at (-1) + setTagSearch (ev.target.value) + + const q: string = ev.target.value.split (' ').at (-1) + if (!(q)) + { + setSuggestions ([]) + return + } + } + + const whenWikiSearchChanged = ev => { + // TODO: 実装 + + setWikiSearch (ev.target.value) + + const q: string = ev.target.value.split (' ').at (-1) + if (!(q)) + { + setSuggestions ([]) + return + } + } + + const whenUserSearchChanged = ev => { + // TODO: 実装 + + setUserSearch (ev.target.value) + + const q: string = ev.target.value.split (' ').at (-1) if (!(q)) { setSuggestions ([]) return } - // void (axios.get(`${ API_BASE_URL }/`)) } const handleKeyDown = (e: React.KeyboardEvent) => { @@ -70,8 +99,8 @@ const TopNav: React.FC = ({ user, setUser }: Props) => { useEffect (() => { if (location.pathname.startsWith ('/posts')) setSelectedMenu (Menu.Post) - else if (location.pathname.startsWith ('/deerjikists')) - setSelectedMenu (Menu.Deerjikist) + else if (location.pathname.startsWith ('/users')) + setSelectedMenu (Menu.User) else if (location.pathname.startsWith ('/tags')) setSelectedMenu (Menu.Tag) else if (location.pathname.startsWith ('/wiki')) @@ -86,9 +115,9 @@ const TopNav: React.FC = ({ user, setUser }: Props) => {
ぼざクリ タグ広場 - +
@@ -112,6 +141,23 @@ const TopNav: React.FC = ({ user, setUser }: Props) => { 投稿追加 ヘルプ
) + case Menu.Tag: + return ( +
+ setSuggestionsVsbl (true)} + onBlur={() => setSuggestionsVsbl (false)} + onKeyDown={handleKeyDown} /> + タグ + 別名タグ + 上位タグ + タグのつけ方 + ヘルプ +
) case Menu.Wiki: return (
@@ -135,6 +181,20 @@ const TopNav: React.FC = ({ user, setUser }: Props) => { 編輯 }
) + case Menu.User: + return ( +
+ setSuggestionsVsbl (true)} + onBlur={() => setSuggestionsVsbl (false)} + onKeyDown={handleKeyDown} /> + 一覧 + {user && お前} +
) } }) ()} ) diff --git a/frontend/src/pages/posts/PostListPage.tsx b/frontend/src/pages/posts/PostListPage.tsx index 5344d13..2d12448 100644 --- a/frontend/src/pages/posts/PostListPage.tsx +++ b/frontend/src/pages/posts/PostListPage.tsx @@ -14,7 +14,7 @@ import type { Post, Tag, WikiPage } from '@/types' export default () => { - const [posts, setPosts] = useState ([]) + const [posts, setPosts] = useState (null) const [wikiPage, setWikiPage] = useState (null) const location = useLocation () @@ -30,7 +30,7 @@ export default () => { .then (res => setPosts (toCamel (res.data, { deep: true }))) .catch (err => { console.error ('Failed to fetch posts:', err) - setPosts ([]) + setPosts (null) })) setWikiPage (null) @@ -53,25 +53,26 @@ export default () => { : `${ SITE_TITLE } 〜 ぼざクリも、ぼざろ外も、外伝もあるんだよ`} - + - {posts.length - ? ( -
- {posts.map (post => ( - - - ))} -
) - : '広場には何もありませんよ.'} + {posts == null ? 'Loading...' : ( + posts.length + ? ( +
+ {posts.map (post => ( + + + ))} +
) + : '広場には何もありませんよ.')}
{(wikiPage && wikiPage.body) && ( - +
Wiki を見る diff --git a/frontend/src/pages/wiki/WikiSearchPage.tsx b/frontend/src/pages/wiki/WikiSearchPage.tsx index 855fb4a..41243d7 100644 --- a/frontend/src/pages/wiki/WikiSearchPage.tsx +++ b/frontend/src/pages/wiki/WikiSearchPage.tsx @@ -1,4 +1,5 @@ import axios from 'axios' +import toCamel from 'camelcase-keys' import React, { useEffect, useState } from 'react' import { Helmet } from 'react-helmet' import { Link } from 'react-router-dom' @@ -17,7 +18,7 @@ export default () => { const search = () => { void (axios.get (`${ API_BASE_URL }/wiki/search`, { params: { title } }) - .then (res => setResults (res.data))) + .then (res => setResults (toCamel (res.data, { deep: true })))) } const handleSearch = (e: React.FormEvent) => { @@ -82,7 +83,7 @@ export default () => { - {page.updated_at} + {page.updatedAt} ))}