File tree Expand file tree Collapse file tree
securing-digital-frontiers/[slug]
terrified-by-linux/[slug] Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ 'use client' ;
2+
3+ import { useState } from 'react' ;
4+
5+ export default function DismissibleBox ( { children } : { children : React . ReactNode } ) {
6+ const [ visible , setVisible ] = useState ( true ) ;
7+
8+ if ( ! visible ) return null ;
9+
10+ return (
11+ < div className = "relative border border-gray-300 rounded-md p-4 bg-gray-200 hover:bg-slate-400 text-slate-800" >
12+ < button
13+ onClick = { ( ) => setVisible ( false ) }
14+ className = "absolute top-2 right-2 text-gray-500 hover:text-red-600 text-sm font-bold"
15+ aria-label = "Close"
16+ >
17+ ✕
18+ </ button >
19+ { children }
20+ </ div >
21+ ) ;
22+ }
Load Diff This file was deleted.
Original file line number Diff line number Diff line change @@ -45,7 +45,7 @@ export function MoreStoriesConcise({ posts }: Props) {
4545 return (
4646 < section >
4747 < div className = "flex justify-between items-center mb-4" >
48- < h2 className = "text-4xl md:text-6xl font-thin tracking-tighter leading-tight" >
48+ < h2 className = "italic text-sm md:text-base font-thin tracking-tighter leading-tight" >
4949 Browse by { sortBy === "title" ? "Title (A–Z)" : "Date (Newest)" }
5050 </ h2 >
5151 < div className = "flex gap-2" >
@@ -82,6 +82,7 @@ export function MoreStoriesConcise({ posts }: Props) {
8282 date = { post . date }
8383 slug = { post . slug }
8484 subPath = { post . subPath }
85+ excerpt = { post . excerpt }
8586 postStatus = { post . postStatus }
8687 />
8788 ) ) }
Original file line number Diff line number Diff line change 1+ // dual use for page.tsx and mdx
2+
3+ import Container from "@/app/_components/preference/container" ;
4+ import { getAllPosts } from "@/lib/api" ;
5+ import { MoreStoriesConcise } from "@/app/_components/post_gen/more-stories-concise"
6+ import { Suspense } from "react" ;
7+
8+ type Props = {
9+ dir : string ;
10+ } ;
11+
12+ export function PostListConcise ( { dir } : Props ) {
13+ const allPosts = getAllPosts ( dir ) ;
14+
15+ return (
16+ < main >
17+ < Container >
18+ < Suspense >
19+ { allPosts . length > 0 && < MoreStoriesConcise posts = { allPosts } /> }
20+ </ Suspense >
21+ </ Container >
22+ </ main >
23+ ) ;
24+
25+ }
Original file line number Diff line number Diff line change @@ -6,6 +6,7 @@ type Props = {
66 date : string ;
77 slug : string ;
88 subPath : string ;
9+ excerpt : string ;
910 postStatus : string ;
1011} ;
1112
@@ -14,14 +15,18 @@ export function TitlePreview({
1415 date,
1516 slug,
1617 subPath,
18+ excerpt,
1719 postStatus,
1820 } : Props )
1921 {
2022 return (
2123 < div >
22- < h3 className = "shadow-sm w-full dark:shadow-sky-900/50 hover:shadow-2xl hover:dark:shadow-zinc-50/100 hover:dark:shadow-lg py-3 px-4 text-2xl mb-3 leading-snug" >
24+ < h3 className = "shadow-sm w-full dark:shadow-sky-900/50 hover:shadow-2xl hover:dark:shadow-zinc-50/100 hover:dark:shadow-lg py-3 px-4 text-xl mb-3 leading-snug" >
2325 < Link href = { `/${ subPath } /${ slug } ` } className = "hover:underline" >
2426 { title }
27+ < p className = "text-pretty text-xs mb-4 italic" >
28+ { excerpt }
29+ </ p >
2530 < p className = "text-right text-xs mb-4 italic" >
2631 { postStatus } < DateFormatter dateString = { date } />
2732 </ p >
Original file line number Diff line number Diff line change 11// for content injections and
22// export to different page.tsx for dynamic language switching
33'use client' ;
4-
54import enFrontierData from '@/lib/_data_exporter/frontier_data_en.mdx' ;
65import zhFrontierData from '@/lib/_data_exporter/frontier_data_zh.mdx' ;
76import enCyberDomainData from '@/lib/_data_exporter/strategic_cyber_domains_en.mdx' ;
87import zhCyberDomainData from '@/lib/_data_exporter/strategic_cyber_domains_zh.mdx' ;
8+ import enCyberThreatsData from '@/lib/_data_exporter/cyber_threats_25_en.mdx' ;
9+ import zhCyberThreatsData from '@/lib/_data_exporter/cyber_threats_25_zh.mdx' ;
910import enBlueprintBattlefieldDataData from '@/lib/_data_exporter/blueprint_to_battlefield_en.mdx' ;
1011import zhBlueprintBattlefieldDataData from '@/lib/_data_exporter/blueprint_to_battlefield_zh.mdx' ;
1112
1213import DisplayLanguageContent from '@/app/_components/language_handler/language-display' ;
1314
1415export const FrontierData = ( ) => {
1516 return < DisplayLanguageContent LanguageChoice = { { en : enFrontierData , zh : zhFrontierData } } />
16- }
17+ } ;
1718
1819export const CyberDomainData = ( ) => {
1920 return < DisplayLanguageContent LanguageChoice = { { en : enCyberDomainData , zh : zhCyberDomainData } } />
20- }
21+ } ;
22+
23+ export const CyberThreatsData = ( ) => {
24+ return < DisplayLanguageContent LanguageChoice = { { en : enCyberThreatsData , zh : zhCyberThreatsData } } />
25+ } ;
2126
2227export const BlueprintBattlefieldData = ( ) => {
2328 return < DisplayLanguageContent LanguageChoice = { { en : enBlueprintBattlefieldDataData , zh : zhBlueprintBattlefieldDataData } } />
24- }
29+ } ;
Original file line number Diff line number Diff line change 1+ // app/_components/toggle-frame.tsx
2+
3+ "use client" ;
4+
5+ import { useState , ReactNode } from "react" ;
6+
7+ type Props = {
8+ label ?: string ;
9+ children : ReactNode ;
10+ } ;
11+
12+ export function ToggleFrame ( { label, children } : Props ) {
13+ const [ open , setOpen ] = useState ( false ) ;
14+
15+ return (
16+ < div className = "my-4" >
17+ < button
18+ onClick = { ( ) => setOpen ( ! open ) }
19+ className = "underline text-blue-800 dark:text-blue-300 hover:text-tkokhing-blue hover:dark:text-tkokhing-dark transition"
20+ >
21+ { open ? `Hide ${ label } ` : `Show ${ label } ` }
22+ </ button >
23+ { open && < div className = "mt-2" > { children } </ div > }
24+ </ div >
25+ ) ;
26+ }
Original file line number Diff line number Diff line change 1- // pull from private repo: [tkokhing/blog_post/_posts] MDX_FOLDER
1+ // [tkokhing/blog_post/_posts] MDX_FOLDER
22import { Metadata } from "next" ;
33import { notFound } from "next/navigation" ;
44import { getPostBySlug } from "@/lib/api" ;
55import { generatePageMetadata } from "@/lib/generatePageMetadata" ;
66import { generatePageStaticParams } from "@/lib/generatePageStaticParams" ;
77import Container from "@/app/_components/preference/container" ;
8- import { FrontierData } from "@/app/_components/preference/data-exporter" ;
98import { PostHeader } from "@/app/_components/post_gen/post-header" ;
109import { PostBody } from "@/app/_components/post_gen/post-body" ;
10+ import { ToggleFrame } from "@/app/_components/preference/toggle-frame" ;
11+ import { FrontierData } from "@/app/_components/preference/data-exporter" ;
12+ import { PostListConcise } from "@/app/_components/post_gen/post-list-concise" ;
1113
1214const MDX_FOLDER = "_posts" ;
1315
@@ -22,6 +24,8 @@ export default async function Post(props: Params) {
2224 const post = getPostBySlug ( params . slug , MDX_FOLDER ) ;
2325 const ImportComponents = {
2426 FrontierData,
27+ ToggleFrame,
28+ PostListConcise,
2529 } ;
2630 if ( ! post ) return notFound ( ) ;
2731
Original file line number Diff line number Diff line change 11// blog/post/ list page
2- import Container from "@/app/_components/preference/container" ;
3- import { getAllPosts } from "@/lib/api" ;
4- import { MoreStoriesConcise } from "@/app/_components/post_gen/more-stories-concise"
5- import { Suspense } from "react" ;
2+ import { PostListConcise } from "@/app/_components/post_gen/post-list-concise" ;
63
7- export default function PostsIndex ( ) {
8- const allPosts = getAllPosts ( "_posts" ) ;
9-
10- return (
11- < main >
12- < Container >
13- < Suspense >
14- { allPosts . length > 0 && < MoreStoriesConcise posts = { allPosts } /> }
15- </ Suspense >
16- </ Container >
17- </ main >
18- ) ;
19- }
4+ export default function BlogPostListPage ( ) {
5+ return < PostListConcise dir = { "_posts" } />
6+ }
Original file line number Diff line number Diff line change 1- // pull from private repo: [tkokhing/frontier_post/_frontier] MDX_FOLDER
1+ // [tkokhing/frontier_post/_frontier] MDX_FOLDER
22import { Metadata } from "next" ;
33import { notFound } from "next/navigation" ;
44import Container from "@/app/_components/preference/container" ;
5- import { CyberDomainData } from "@/app/_components/preference/data-exporter" ;
6- import { BlueprintBattlefieldData } from "@/app/_components/preference/data-exporter" ;
75import { PostHeader } from "@/app/_components/post_gen/post-header" ;
86import { PostBody } from "@/app/_components/post_gen/post-body" ;
97import { getPostBySlug } from "@/lib/api" ;
108import { generatePageMetadata } from "@/lib/generatePageMetadata" ;
119import { generatePageStaticParams } from "@/lib/generatePageStaticParams" ;
12-
10+ import { CyberDomainData } from "@/app/_components/preference/data-exporter" ;
11+ import { BlueprintBattlefieldData } from "@/app/_components/preference/data-exporter" ;
12+ import { CyberThreatsData } from "@/app/_components/preference/data-exporter" ;
1313const MDX_FOLDER = "_frontier" ;
1414
1515type Params = {
@@ -23,6 +23,7 @@ export default async function Post(props: Params) {
2323 const post = getPostBySlug ( params . slug , MDX_FOLDER ) ;
2424 const ImportComponents = {
2525 CyberDomainData,
26+ CyberThreatsData,
2627 BlueprintBattlefieldData,
2728 } ;
2829 if ( ! post ) return notFound ( ) ;
You can’t perform that action at this time.
0 commit comments