Skip to content

Commit 99403fc

Browse files
committed
refine
1 parent 91c3917 commit 99403fc

22 files changed

+499
-156
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/pages/ArchivePage.astro

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
import { getCollection } from 'astro:content';
33
import BaseLayout from '../../layouts/BaseLayout.astro';
44
import { ARCHIVE_TEXT } from '../../i18n/ui';
5-
import { getLocalePrefix, resolveLocale, type Locale } from '../../i18n/config';
5+
import { getLocalePrefix, type Locale } from '../../i18n/config';
6+
import { getAlternateLocale, toBcpLocale } from '../../utils/localeUtils';
67
78
interface Props {
89
locale: Locale;
910
}
1011
11-
const { locale: incomingLocale } = Astro.props as Props;
12-
const locale = resolveLocale(incomingLocale);
12+
const { locale } = Astro.props as Props;
1313
const localePrefix = getLocalePrefix(locale);
1414
const archiveText = ARCHIVE_TEXT[locale];
15-
const altLocale: Locale = locale === 'ko' ? 'en' : 'ko';
16-
const bcpLocale = locale === 'ko' ? 'ko-KR' : 'en-US';
17-
const altBcpLocale = altLocale === 'ko' ? 'ko-KR' : 'en-US';
15+
const altLocale = getAlternateLocale(locale);
16+
const bcpLocale = toBcpLocale(locale);
17+
const altBcpLocale = toBcpLocale(altLocale);
1818
const altPrefix = getLocalePrefix(altLocale);
1919
const alternatePath = `${altPrefix}/archive`.replace(/\/{2,}/g, '/');
2020

src/components/pages/HomePage.astro

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
---
2+
import { ViewTransitions } from 'astro:transitions';
23
import { getCollection, type CollectionEntry } from 'astro:content';
34
import readingTime from 'reading-time';
45
import LanguageToggle from '../LanguageToggle.astro';
56
import { COMMON_TEXT, NAV_TEXT, HOME_TEXT, POST_TEXT } from '../../i18n/ui';
67
import { getLocalePrefix, resolveLocale, type Locale } from '../../i18n/config';
8+
import { isActiveLink as checkActiveLink } from '../../utils/linkUtils';
9+
import { formatDate } from '../../utils/dateFormatter';
710
import '../../styles/global.css';
811
import mainScript from '../../scripts/main.js?url';
912
1013
interface Props {
1114
locale: Locale;
1215
}
1316
14-
const { locale: incomingLocale } = Astro.props as Props;
15-
const locale = resolveLocale(incomingLocale);
17+
const { locale } = Astro.props as Props;
1618
1719
const allEntries: CollectionEntry<'entries'>[] = await getCollection('entries', ({ data }) => !data.draft && data.lang === locale);
1820
const sortedEntries = allEntries.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
@@ -43,16 +45,7 @@ const navLinks = [
4345
];
4446
const tagsPageHref = buildPath(`${localePrefix}/tags`);
4547
const currentPath = Astro.url.pathname;
46-
const isActiveLink = (href: string) => {
47-
const normalizedHref = href.endsWith('/') && href !== '/' ? href.slice(0, -1) : href;
48-
const normalizedPath = currentPath.endsWith('/') && currentPath !== '/' ? currentPath.slice(0, -1) : currentPath;
49-
50-
if (normalizedHref === '/' || normalizedHref === '/en') {
51-
return normalizedPath === normalizedHref;
52-
}
53-
54-
return normalizedPath === normalizedHref || normalizedPath.startsWith(`${normalizedHref}/`);
55-
};
48+
const isActiveLink = (href: string) => checkActiveLink(href, currentPath);
5649
---
5750

5851
<!DOCTYPE html>
@@ -77,6 +70,8 @@ const isActiveLink = (href: string) => {
7770

7871
<!-- RSS -->
7972
<link rel="alternate" type="application/rss+xml" title="Code Brewer RSS Feed" href="/feed.xml" />
73+
74+
<ViewTransitions />
8075
</head>
8176
<body>
8277
<!-- Mobile Header -->
@@ -173,13 +168,7 @@ const isActiveLink = (href: string) => {
173168
</button>
174169
</div>
175170
{postsWithContent.map(({ post, Content, readingTime, pathSlug }, index) => {
176-
const formattedDate = post.data.date
177-
.toLocaleDateString(locale === 'ko' ? 'ko-KR' : 'en-US', {
178-
year: 'numeric',
179-
month: '2-digit',
180-
day: '2-digit'
181-
})
182-
.replace(/\//g, '. ');
171+
const formattedDate = formatDate(post.data.date, locale);
183172

184173
const readingMinutes = Math.ceil(readingTime);
185174
const readingTimeText = locale === 'ko'

src/components/pages/PostPage.astro

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
import { type CollectionEntry } from 'astro:content';
33
import BaseLayout from '../../layouts/BaseLayout.astro';
44
import { POST_TEXT } from '../../i18n/ui';
5-
import { getLocalePrefix, resolveLocale, type Locale } from '../../i18n/config';
5+
import { getLocalePrefix, type Locale } from '../../i18n/config';
6+
import { formatDate } from '../../utils/dateFormatter';
67
import readingTime from 'reading-time';
78
89
interface Props {
@@ -12,8 +13,7 @@ interface Props {
1213
alternateSlug?: string;
1314
}
1415
15-
const { post, locale: incomingLocale, pathSlug, alternateSlug } = Astro.props as Props;
16-
const locale = resolveLocale(incomingLocale);
16+
const { post, locale, pathSlug, alternateSlug } = Astro.props as Props;
1717
const localePrefix = getLocalePrefix(locale);
1818
const postText = POST_TEXT[locale];
1919
const buildPath = (path: string) => path.replace(/\/{2,}/g, '/');
@@ -23,13 +23,7 @@ const { Content } = await post.render();
2323
const stats = readingTime(post.body);
2424
const readingMinutes = Math.ceil(stats.minutes);
2525
26-
const formattedDate = post.data.date
27-
.toLocaleDateString(locale === 'ko' ? 'ko-KR' : 'en-US', {
28-
year: 'numeric',
29-
month: '2-digit',
30-
day: '2-digit'
31-
})
32-
.replace(/\//g, '. ');
26+
const formattedDate = formatDate(post.data.date, locale);
3327
3428
const readingTimeText = locale === 'ko'
3529
? `${readingMinutes}${postText.readingTime}`

src/components/pages/RandomRedirect.astro

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
---
2+
import { ViewTransitions } from 'astro:transitions';
23
import { getCollection } from 'astro:content';
3-
import { getLocalePrefix, resolveLocale, type Locale } from '../../i18n/config';
4+
import { getLocalePrefix, type Locale } from '../../i18n/config';
45
56
interface Props {
67
locale: Locale;
78
}
89
9-
const { locale: incomingLocale } = Astro.props as Props;
10-
const locale = resolveLocale(incomingLocale);
10+
const { locale } = Astro.props as Props;
1111
1212
const entries = await getCollection('entries', ({ data }) => !data.draft && data.lang === locale);
1313
@@ -17,15 +17,10 @@ const candidates = entries.map((entry) => ({
1717
url: `${localePrefix}/posts/${entry.data.translationKey ?? entry.slug}`.replace(/\/\//g, '/'),
1818
}));
1919
20-
const randomEntry = candidates.length > 0
21-
? candidates[Math.floor(Math.random() * candidates.length)]
22-
: undefined;
23-
24-
const randomUrl = randomEntry?.url ?? (localePrefix || '/');
2520
const loadingText = locale === 'ko' ? '랜덤 기록을 불러오는 중...' : 'Loading a random entry...';
2621
const emptyText = locale === 'ko' ? '표시할 기록이 없습니다.' : 'No entries available.';
2722
const pageTitle = locale === 'ko' ? '랜덤 기록 - Code Brewer' : 'Random Entry - Code Brewer';
28-
const shouldRedirect = Boolean(randomEntry);
23+
const fallbackUrl = localePrefix || '/';
2924
---
3025

3126
<!DOCTYPE html>
@@ -34,10 +29,32 @@ const shouldRedirect = Boolean(randomEntry);
3429
<meta charset="UTF-8" />
3530
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
3631
<title>{pageTitle}</title>
37-
{shouldRedirect && <meta http-equiv="refresh" content={`0;url=${randomUrl}`} />}
38-
{shouldRedirect && (
39-
<script is:inline>{`window.location.href = '${randomUrl}';`}</script>
40-
)}
32+
<ViewTransitions />
33+
<script is:inline define:vars={{ candidates, fallbackUrl }}>
34+
// Pick random entry on EVERY page load (client-side)
35+
const pickRandomAndNavigate = () => {
36+
if (candidates && candidates.length > 0) {
37+
const randomIndex = Math.floor(Math.random() * candidates.length);
38+
const randomUrl = candidates[randomIndex].url;
39+
40+
console.log('Redirecting to:', randomUrl);
41+
42+
// Create a link and click it to trigger View Transitions
43+
const link = document.createElement('a');
44+
link.href = randomUrl;
45+
link.style.display = 'none';
46+
document.body.appendChild(link);
47+
link.click();
48+
document.body.removeChild(link);
49+
} else {
50+
// No entries available, redirect to home
51+
window.location.href = fallbackUrl;
52+
}
53+
};
54+
55+
// Small delay to show loading animation
56+
setTimeout(pickRandomAndNavigate, 300);
57+
</script>
4158
<style>
4259
body {
4360
margin: 0;
@@ -70,7 +87,7 @@ const shouldRedirect = Boolean(randomEntry);
7087
<body>
7188
<div class="loader">
7289
<div class="spinner"></div>
73-
<p>{shouldRedirect ? loadingText : emptyText}</p>
90+
<p>{candidates.length > 0 ? loadingText : emptyText}</p>
7491
</div>
7592
</body>
7693
</html>

src/components/pages/TagDetailPage.astro

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,22 @@ import { getCollection } from 'astro:content';
33
import BaseLayout from '../../layouts/BaseLayout.astro';
44
import { TAGS_TEXT } from '../../i18n/ui';
55
import { getLocalePrefix, resolveLocale, type Locale } from '../../i18n/config';
6+
import { getAlternateLocale, toBcpLocale } from '../../utils/localeUtils';
7+
import { formatTagLabel } from '../../utils/tagFormatter';
68
79
interface Props {
810
locale: Locale;
911
tag: string;
1012
}
1113
12-
const { locale: incomingLocale, tag } = Astro.props as Props;
13-
const locale = resolveLocale(incomingLocale);
14+
const { locale, tag } = Astro.props as Props;
1415
const localePrefix = getLocalePrefix(locale);
1516
const text = TAGS_TEXT[locale];
1617
const decodedTag = decodeURIComponent(tag);
17-
const altLocale: Locale = locale === 'ko' ? 'en' : 'ko';
18+
const altLocale = getAlternateLocale(locale);
1819
const altPrefix = getLocalePrefix(altLocale);
1920
const alternatePath = `${altPrefix}/tags/${encodeURIComponent(decodedTag)}`.replace(/\/\//g, '/');
2021
21-
const formatTagLabel = (value: string) => {
22-
if (value.toLowerCase().startsWith('author:')) {
23-
const name = value.slice(value.indexOf(':') + 1).trim();
24-
return locale === 'ko' ? `저자: ${name}` : `Author: ${name}`;
25-
}
26-
return value;
27-
};
28-
2922
const entries = await getCollection('entries', ({ data }) => !data.draft && data.lang === locale && data.tags.includes(decodedTag));
3023
const altEntries = await getCollection('entries', ({ data }) => !data.draft && data.lang === altLocale && data.tags.includes(decodedTag));
3124
@@ -39,7 +32,7 @@ const mappedEntries = entries
3932
4033
const hasAlternateEntries = altEntries.length > 0;
4134
42-
const formatDate = (date: Date) => date.toLocaleDateString(locale === 'ko' ? 'ko-KR' : 'en-US', {
35+
const formatDateShort = (date: Date) => date.toLocaleDateString(toBcpLocale(locale), {
4336
year: 'numeric',
4437
month: 'short',
4538
day: 'numeric',
@@ -54,7 +47,7 @@ const formatDate = (date: Date) => date.toLocaleDateString(locale === 'ko' ? 'ko
5447
<div class="tag-detail-container">
5548
<header class="tag-detail-header">
5649
<a href={`${localePrefix}/tags`.replace(/\/\//g, '/')} class="tag-detail-back">← {text.backToAll}</a>
57-
<h1>{text.taggedWith(formatTagLabel(decodedTag))}</h1>
50+
<h1>{text.taggedWith(formatTagLabel(decodedTag, locale))}</h1>
5851
</header>
5952

6053
{mappedEntries.length === 0 ? (
@@ -66,7 +59,7 @@ const formatDate = (date: Date) => date.toLocaleDateString(locale === 'ko' ? 'ko
6659
<a href={entry.url} class="tag-detail-link">
6760
<span class="tag-detail-title">{entry.title}</span>
6861
<span class="tag-detail-meta">
69-
{formatDate(entry.date)}
62+
{formatDateShort(entry.date)}
7063
</span>
7164
</a>
7265
</li>

src/components/pages/TagsPage.astro

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@ import { getCollection, type CollectionEntry } from 'astro:content';
33
import BaseLayout from '../../layouts/BaseLayout.astro';
44
import { TAGS_TEXT } from '../../i18n/ui';
55
import { getLocalePrefix, resolveLocale, type Locale } from '../../i18n/config';
6+
import { getAlternateLocale, toBcpLocale } from '../../utils/localeUtils';
7+
import { formatTagLabel } from '../../utils/tagFormatter';
68
79
interface Props {
810
locale: Locale;
911
}
1012
11-
const { locale: incomingLocale } = Astro.props as Props;
12-
const locale = resolveLocale(incomingLocale);
13+
const { locale } = Astro.props as Props;
1314
const localePrefix = getLocalePrefix(locale);
1415
const text = TAGS_TEXT[locale];
15-
const altLocale: Locale = locale === 'ko' ? 'en' : 'ko';
16+
const altLocale = getAlternateLocale(locale);
1617
const altPrefix = getLocalePrefix(altLocale);
1718
const alternatePath = `${altPrefix}/tags`.replace(/\/\//g, '/');
1819
@@ -55,15 +56,7 @@ entries.forEach((entry) => {
5556
5657
alternateEntries.forEach((entry) => addCount(altTagCounts, entry.data.tags));
5758
58-
const collator = new Intl.Collator(locale === 'ko' ? 'ko-KR' : 'en-US');
59-
60-
const formatTagLabel = (value: string) => {
61-
if (value.toLowerCase().startsWith('author:')) {
62-
const name = value.slice(value.indexOf(':') + 1).trim();
63-
return locale === 'ko' ? `저자: ${name}` : `Author: ${name}`;
64-
}
65-
return value;
66-
};
59+
const collator = new Intl.Collator(toBcpLocale(locale));
6760
6861
const searchQueryParam = Astro.url.searchParams.get('q');
6962
const initialQuery = searchQueryParam ? searchQueryParam.trim() : '';
@@ -80,7 +73,7 @@ const tags = Array.from(tagMap.entries())
8073
currentCount: sortedEntries.length,
8174
altCount,
8275
totalCount,
83-
label: formatTagLabel(tag),
76+
label: formatTagLabel(tag, locale),
8477
};
8578
})
8679
.sort((a, b) => {
@@ -93,7 +86,7 @@ const tags = Array.from(tagMap.entries())
9386
return collator.compare(a.tag, b.tag);
9487
});
9588
96-
const formatDate = (date: Date) => date.toLocaleDateString(locale === 'ko' ? 'ko-KR' : 'en-US', {
89+
const formatDateShort = (date: Date) => date.toLocaleDateString(toBcpLocale(locale), {
9790
year: 'numeric',
9891
month: 'short',
9992
day: 'numeric',
@@ -159,7 +152,7 @@ const formatDate = (date: Date) => date.toLocaleDateString(locale === 'ko' ? 'ko
159152
<a href={entry.url} class="tag-entry-link">
160153
<span class="tag-entry-title">{entry.title}</span>
161154
<span class="tag-entry-meta">
162-
{formatDate(entry.date)}
155+
{formatDateShort(entry.date)}
163156
</span>
164157
</a>
165158
</li>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
title: "will I regret"
3+
date: 2022-01-16
4+
tags: ["question", "reflection", "happiness"]
5+
draft: true
6+
lang: en
7+
translationKey: "will-i-regret"
8+
---
9+
10+
## Introduction
11+
12+
Write your entry content here...
13+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
title: "will I regret"
3+
date: 2022-01-16
4+
tags: ["질문", "후회", "행복"]
5+
draft: true
6+
lang: ko
7+
translationKey: "will-i-regret"
8+
---
9+
10+
## Introduction
11+
12+
Write your entry content here...
13+

0 commit comments

Comments
 (0)