diff options
Diffstat (limited to 'src/app/article')
-rw-r--r-- | src/app/article/_components/pagenationElement.tsx | 100 | ||||
-rw-r--r-- | src/app/article/all/[pageId]/page.tsx | 122 | ||||
-rw-r--r-- | src/app/article/tag/[tagName]/[pageNum]/page.tsx | 54 | ||||
-rw-r--r-- | src/app/article/tag/[tagName]/page.tsx | 33 |
4 files changed, 182 insertions, 127 deletions
diff --git a/src/app/article/_components/pagenationElement.tsx b/src/app/article/_components/pagenationElement.tsx new file mode 100644 index 0000000..79191bc --- /dev/null +++ b/src/app/article/_components/pagenationElement.tsx @@ -0,0 +1,100 @@ +import Link from "next/link"; +import { createPagenation } from "../../../util/pagenation"; + +export function pagenationElement(now: number, max: number, getHrefBuilder: (page: number) => string) { + const pagenationData = createPagenation({ now: now, max: max, between: 2 }); + const liElements: JSX.Element[] = []; + for (const v of pagenationData) { + if (v.type == "back") { + if (v.link == null) { + liElements.push( + <li key={v.key}> + <span className="flex items-center justify-center px-4 h-10 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"> + <span className="sr-only">Previous</span> + <svg className="w-3 h-3 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10"> + <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 1 1 5l4 4" /> + </svg> + </span> + </li> + ); + } else { + liElements.push( + <li key={v.key}> + <Link href={getHrefBuilder(v.link)} className="flex items-center justify-center px-4 h-10 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"> + <span className="sr-only">Previous</span> + <svg className="w-3 h-3 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10"> + <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 1 1 5l4 4" /> + </svg> + </Link> + </li> + ); + } + } else if (v.type == "next") { + if (v.link == null) { + liElements.push( + <li key={v.key}> + <span className="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 rounded-e-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"> + <span className="sr-only">Next</span> + <svg className="w-3 h-3 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10"> + <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4" /> + </svg> + </span> + </li> + ); + } else { + liElements.push( + <li key={v.key}> + <Link href={getHrefBuilder(v.link)} className="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 rounded-e-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"> + <span className="sr-only">Next</span> + <svg className="w-3 h-3 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10"> + <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4" /> + </svg> + </Link> + </li> + ); + } + } else if (v.type == "num") { + if (v.link == null) { + if (v.num == now) { + liElements.push( + <li key={v.key}> + <span + className="z-10 flex items-center justify-center px-4 h-10 leading-tight text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white" + >{v.num}</span> + </li> + ); + } else { + liElements.push( + <li key={v.key}> + <span + className="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white" + >{v.num}</span> + </li> + ); + } + } else { + liElements.push( + <li key={v.key}> + <Link + href={getHrefBuilder(v.link)} + className="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white" + >{v.num}</Link> + </li> + ); + } + } else if (v.type == "sp") { + <li key={v.key}> + <span + className="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white" + >...</span> + </li> + } + } + return ( + <nav className="flex justify-center pt-10"> + <ul className="flex items-center -space-x-px h-10 text-base"> + {liElements} + </ul> + </nav> + ); +} diff --git a/src/app/article/all/[pageId]/page.tsx b/src/app/article/all/[pageId]/page.tsx index 622edbb..2b9685c 100644 --- a/src/app/article/all/[pageId]/page.tsx +++ b/src/app/article/all/[pageId]/page.tsx @@ -1,8 +1,9 @@ -import Link from "next/link"; import { ArticleLoader } from "../../../../util/articleLoader"; import dateformat from "dateformat"; -import { createPagenation } from "../../../../util/pagenation"; import { ArticleListElement } from "../../_components/articleListElement"; +import { PPV } from "../../../../util/consts"; +import { chunk } from "../../../../util/arrayChunk"; +import { pagenationElement } from "../../_components/pagenationElement"; dateformat.i18n.dayNames = [ '日', '月', '火', '水', '木', '金', '土', '日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日' @@ -26,119 +27,21 @@ export default async function Page(context: PageType) { const displayData = chunkdData[pageId - 1]; return ( <div className="p-1 gap-16"> - {pagenationElement(pageId, chunkdData.length)} + {pagenationElement(pageId, chunkdData.length, getHrefBuilder)} <div className="text-right">全:{loadedData.articles.length}件</div> {ArticleListElement(displayData, loadedData.categoryTag)} - {pagenationElement(pageId, chunkdData.length)} + {pagenationElement(pageId, chunkdData.length, getHrefBuilder)} </div> ); } -function pagenationElement(now: number, max: number) { - const pagenationData = createPagenation({ now: now, max: max, between: 2 }); - const liElements: JSX.Element[] = []; - for (const v of pagenationData) { - if (v.type == "back") { - if (v.link == null) { - liElements.push( - <li key={v.key}> - <span className="flex items-center justify-center px-4 h-10 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"> - <span className="sr-only">Previous</span> - <svg className="w-3 h-3 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10"> - <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 1 1 5l4 4" /> - </svg> - </span> - </li> - ); - } else { - liElements.push( - <li key={v.key}> - <Link href={`/article/all/page-${v.link}`} className="flex items-center justify-center px-4 h-10 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"> - <span className="sr-only">Previous</span> - <svg className="w-3 h-3 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10"> - <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 1 1 5l4 4" /> - </svg> - </Link> - </li> - ); - } - } else if (v.type == "next") { - if (v.link == null) { - liElements.push( - <li key={v.key}> - <span className="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 rounded-e-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"> - <span className="sr-only">Next</span> - <svg className="w-3 h-3 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10"> - <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4" /> - </svg> - </span> - </li> - ); - } else { - liElements.push( - <li key={v.key}> - <Link href={`/article/all/page-${v.link}`} className="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 rounded-e-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"> - <span className="sr-only">Next</span> - <svg className="w-3 h-3 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10"> - <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4" /> - </svg> - </Link> - </li> - ); - } - } else if (v.type == "num") { - if (v.link == null) { - if (v.num == now) { - liElements.push( - <li key={v.key}> - <span - className="z-10 flex items-center justify-center px-4 h-10 leading-tight text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white" - >{v.num}</span> - </li> - ); - } else { - liElements.push( - <li key={v.key}> - <span - className="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white" - >{v.num}</span> - </li> - ); - } - } else { - liElements.push( - <li key={v.key}> - <Link - href={`/article/all/page-${v.link}`} - className="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white" - >{v.num}</Link> - </li> - ); - } - } else if (v.type == "sp") { - <li key={v.key}> - <span - className="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white" - >...</span> - </li> - } - } - return ( - <nav className="flex justify-center pt-10"> - <ul className="flex items-center -space-x-px h-10 text-base"> - {liElements} - </ul> - </nav> - ); +function getHrefBuilder(page: number): string { + return `/article/all/page-${page}`; } function getPageIdNumber(pageIdStr: string) { const m = pageIdStr.match(/page-(\d+)/)!; const id = Number(m[1]); return id; } -const PPV = Number(process.env["AKIBA_SOUKEN_AR_ITEM_PPV"] ?? "100"); -if (!Number.isInteger(PPV)) { - throw new Error(`AKIBA_SOUKEN_AR_ITEM_PPVに整数をセットして下さい`); -} //export const dynamicParams = true; export async function generateStaticParams() { const loadedData = await ArticleLoader.instance.loadData(); @@ -147,14 +50,3 @@ export async function generateStaticParams() { return { pageId: `page-${index + 1}`, data: data }; }); } - -function chunk<T = any>(list: T[], len: number) { - if (len <= 0) { - throw new Error(); - } - const result: T[][] = []; - for (let i = 0; i < list.length; i += len) { - result.push(list.slice(i, i + len)); - } - return result; -}
\ No newline at end of file diff --git a/src/app/article/tag/[tagName]/[pageNum]/page.tsx b/src/app/article/tag/[tagName]/[pageNum]/page.tsx new file mode 100644 index 0000000..1820f65 --- /dev/null +++ b/src/app/article/tag/[tagName]/[pageNum]/page.tsx @@ -0,0 +1,54 @@ +import { chunk } from "../../../../../util/arrayChunk"; +import { ArticleLoader } from "../../../../../util/articleLoader"; +import { PPV } from "../../../../../util/consts"; +import { ArticleListElement } from "../../../_components/articleListElement"; +import { pagenationElement } from "../../../_components/pagenationElement"; + +type PageType = { + searchParams: Record<string, string>, + params: { + tagName: string, + pageNum: string, + } +} +export async function generateMetadata(context: PageType) { + return { + title: `アキバ総研アーカイブ:タグの記事一覧 ${context.params.tagName}`, + } +} +export default async function Page(context: PageType) { + const pageNumber = Number(context.params.pageNum); + const nowPageTagName = decodeURIComponent(context.params.tagName); + const categoryTag = await ArticleLoader.instance.getCategoryTag(); + const loadedData = await ArticleLoader.instance.getTagArticle(nowPageTagName); + const chunkdData = chunk(loadedData, PPV); + const displayData = chunkdData[pageNumber - 1]; + return ( + <div className="p-1 gap-16"> + <div className="text-center">タグ:{nowPageTagName} の記事一覧</div> + <div className="text-right">全:{loadedData.length}件</div> + {pagenationElement(pageNumber, chunkdData.length, getHrefBuilder(nowPageTagName))} + {ArticleListElement(displayData, categoryTag)} + {pagenationElement(pageNumber, chunkdData.length, getHrefBuilder(nowPageTagName))} + </div> + ); +} +function getHrefBuilder(tagName: string) { + return (page: number) => { + if (page == 1) { + return `/article/tag/${tagName}/`; + } else { + return `/article/tag/${tagName}/${page}/`; + } + } +} +export async function generateStaticParams() { + const articleData = await ArticleLoader.instance.loadData(); + const result: PageType["params"][] = []; + for (const [tag, data] of articleData.categoryTag.data) { + for (let page = 2; page <= Math.ceil(data.count / PPV); page++) { + result.push({ tagName: tag, pageNum: String(page) }); + } + } + return result; +} diff --git a/src/app/article/tag/[tagName]/page.tsx b/src/app/article/tag/[tagName]/page.tsx index 7fbce4c..4cef1d3 100644 --- a/src/app/article/tag/[tagName]/page.tsx +++ b/src/app/article/tag/[tagName]/page.tsx @@ -1,5 +1,8 @@ +import { chunk } from "../../../../util/arrayChunk"; import { ArticleLoader } from "../../../../util/articleLoader"; +import { PPV } from "../../../../util/consts"; import { ArticleListElement } from "../../_components/articleListElement"; +import { pagenationElement } from "../../_components/pagenationElement"; type PageType = { searchParams: Record<string, string>, params: { @@ -13,24 +16,30 @@ export async function generateMetadata(context: PageType) { } export default async function Page(context: PageType) { const nowPageTagName = decodeURIComponent(context.params.tagName); - const loadedData = await ArticleLoader.instance.loadData() - const filterdArticles = loadedData.articles.filter(article => { - if (article.tags.includes(nowPageTagName)) { - return true; - } - if (article.breadLinks.includes(nowPageTagName)) { - return true; - } - return false; - }); + const categoryTag = await ArticleLoader.instance.getCategoryTag(); + const loadedData = await ArticleLoader.instance.getTagArticle(nowPageTagName); + const chunkdData = chunk(loadedData, PPV); + const displayData = chunkdData[0]; return ( <div className="p-1 gap-16"> <div className="text-center">タグ:{nowPageTagName} の記事一覧</div> - <div className="text-right">全:{filterdArticles.length}件</div> - {ArticleListElement(filterdArticles, loadedData.categoryTag)} + <div className="text-right">全:{loadedData.length}件</div> + {pagenationElement(1, chunkdData.length, getHrefBuilder(nowPageTagName))} + {ArticleListElement(displayData, categoryTag)} + {pagenationElement(1, chunkdData.length, getHrefBuilder(nowPageTagName))} </div> ); } +function getHrefBuilder(tagName: string) { + return (page: number) => { + if (page == 1) { + return `/article/tag/${tagName}/`; + } else { + return `/article/tag/${tagName}/${page}/`; + } + } +} + export async function generateStaticParams() { const articleData = await ArticleLoader.instance.loadData(); const result: { tagName: string }[] = []; |