diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..1d9e349
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,2 @@
+# SEO Site URL
+VITE_SEO_SITE_URL=http://localhost:5173
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..fb97241
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,34 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+The format is based on [Keep a Changelog](https://keepachangelog.com/),
+and this project adheres to [Semantic Versioning](https://semver.org/).
+
+## [1.1.2] - 2026-03-02
+
+### Changed
+- Refined sample datasets to better demonstrate JSON tree navigation and edge cases.
+
+### Removed
+- Removed the integrated Changelog page from the system UI.
+
+## [1.1.1] - 2026-02-24
+
+### Added
+- Added syntax highlighting for JSONPath expressions to improve visual readability.
+
+## [1.1.0] - 2026-02-24
+
+### Added
+- Implemented sortable table views for JSON arrays with CSV export functionality.
+- Introduced a dedicated tool layout featuring a categorised sidebar menu for efficient switching.
+- Added one-click functionality to copy JSONPath-selected data as raw JSON.
+- Categorised tools into "JSON Processing" (Viewer, Grid) and "Daily Tools" (BMI Calculator).
+
+## [1.0.0] - 2026-01-19
+
+### Added
+- Initial release.
+- Full-featured JSON viewer with JSONPath query support and CSV export.
+- BMI calculator with category guidance and health advice.
+- Internationalisation support for British English and Simplified Chinese.
diff --git a/src/components/footer/index.tsx b/src/components/footer/index.tsx
new file mode 100644
index 0000000..c1ab047
--- /dev/null
+++ b/src/components/footer/index.tsx
@@ -0,0 +1,18 @@
+import { useTranslation } from "react-i18next"
+import { useMemo } from "react"
+import dayjs from "dayjs"
+
+export default function Footer() {
+ const { t } = useTranslation()
+ const today = useMemo(() => dayjs(), [])
+
+ return (
+
+ )
+}
diff --git a/src/components/header/index.tsx b/src/components/header/index.tsx
new file mode 100644
index 0000000..aebf9fb
--- /dev/null
+++ b/src/components/header/index.tsx
@@ -0,0 +1,39 @@
+import { Link } from "react-router-dom"
+import { useTranslation } from "react-i18next"
+import LanguageSwitcher from "@/components/language-switcher"
+
+export default function Header() {
+ const { t } = useTranslation()
+
+ return (
+
+
+
+
+
{t("app.title")}
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/json-code-editor/index.tsx b/src/components/json-code-editor/index.tsx
index 1f0c1e8..973815a 100644
--- a/src/components/json-code-editor/index.tsx
+++ b/src/components/json-code-editor/index.tsx
@@ -1,4 +1,4 @@
-import { useMemo, useRef } from "react"
+import React, { useMemo, useRef } from "react"
type JsonCodeEditorProps = {
value: string
diff --git a/src/components/seo/index.tsx b/src/components/seo/index.tsx
index 5fd430c..fee722f 100644
--- a/src/components/seo/index.tsx
+++ b/src/components/seo/index.tsx
@@ -7,7 +7,7 @@ type SeoProps = {
path: string
}
-const SITE_URL = "https://dev-lab.onixbyte.dev"
+const SITE_URL = import.meta.env.VITE_SEO_SITE_URL
const DEFAULT_IMAGE = `${SITE_URL}/onixbyte.svg`
function setMetaTag(selector: string, attr: string, value: string) {
diff --git a/src/layout/hero-layout/index.tsx b/src/layout/hero-layout/index.tsx
index aa44f94..0b5f43e 100644
--- a/src/layout/hero-layout/index.tsx
+++ b/src/layout/hero-layout/index.tsx
@@ -3,6 +3,8 @@ import { useMemo } from "react"
import { useTranslation } from "react-i18next"
import dayjs from "dayjs"
import LanguageSwitcher from "@/components/language-switcher"
+import Header from "@/components/header"
+import Footer from "@/components/footer"
/**
* Main application component that serves as the root layout.
@@ -15,46 +17,7 @@ export default function HeroLayout() {
return (
{/* Navigation Header */}
-
-
-
-
-
- {t("app.title")}
-
-
-
-
-
-
-
-
-
+
{/* Main Content Area */}
@@ -62,13 +25,7 @@ export default function HeroLayout() {
{/* Footer */}
-
+
)
}
diff --git a/src/layout/tools-layout/index.tsx b/src/layout/tools-layout/index.tsx
index 43982c9..7516d75 100644
--- a/src/layout/tools-layout/index.tsx
+++ b/src/layout/tools-layout/index.tsx
@@ -3,6 +3,8 @@ import { Link, NavLink, Outlet } from "react-router-dom"
import { useTranslation } from "react-i18next"
import dayjs from "dayjs"
import LanguageSwitcher from "@/components/language-switcher"
+import Header from "@/components/header"
+import Footer from "@/components/footer"
export default function ToolsLayout() {
const today = useMemo(() => dayjs(), [])
@@ -28,40 +30,7 @@ export default function ToolsLayout() {
return (
-
-
-
-
-
{t("app.title")}
-
-
-
-
-
-
-
-
+
@@ -120,13 +89,7 @@ export default function ToolsLayout() {
-
+
)
}
diff --git a/src/page/changelog/index.tsx b/src/page/changelog/index.tsx
deleted file mode 100644
index 4705b09..0000000
--- a/src/page/changelog/index.tsx
+++ /dev/null
@@ -1,153 +0,0 @@
-import { useMemo } from "react"
-import { useTranslation } from "react-i18next"
-import Seo from "@/components/seo"
-
-interface ChangeEntry {
- type: "feat" | "fix" | "refactor" | "chore"
- title: string
- description?: string
- date?: string
-}
-
-interface ChangelogVersion {
- version: string
- date: string
- entries: ChangeEntry[]
-}
-
-const CHANGELOG_DATA: ChangelogVersion[] = [
- {
- version: "1.1.1",
- date: "2026-02-24",
- entries: [
- {
- type: "feat",
- title: "JSON Path Highlighting",
- description: "Add highlighting for JSON Path expression."
- }
- ]
- },
- {
- version: "1.1.0",
- date: "2026-02-24",
- entries: [
- {
- type: "feat",
- title: "JSON Grid",
- description: "Convert JSON arrays into sortable table view with CSV export functionality"
- },
- {
- type: "feat",
- title: "Tools Layout with Collapsible Menu",
- description: "Added a dedicated tools layout with categorised sidebar menu for quick tool switching",
- },
- {
- type: "feat",
- title: "Copy Selected JSON Feature",
- description: "Added ability to copy JSONPath selected data as raw JSON with one-click action",
- },
- {
- type: "feat",
- title: "Tool Categories",
- description: "Organised tools into JSON Processing (JSON Viewer, JSON Grid) and Daily Tools (BMI Calculator)",
- },
- {
- type: "fix",
- title: "Live Application Link",
- description: "Updated live application link in README",
- },
- ],
- },
- {
- version: "1.0.0",
- date: "2026-01-19",
- entries: [
- {
- type: "feat",
- title: "JSON Viewer with JSONPath",
- description: "Full-featured JSON viewer with JSONPath query support and CSV export",
- },
- {
- type: "feat",
- title: "BMI Calculator",
- description: "Calculate Body Mass Index with category guidance and health advice",
- },
- {
- type: "feat",
- title: "Internationalization",
- description: "Support for English (GB) and Simplified Chinese with language switcher",
- },
- ],
- },
-]
-
-type ChangeTypeKey = "feat" | "fix" | "refactor" | "chore"
-
-export default function Changelog() {
- const { t } = useTranslation()
-
- const changeTypeLabels = useMemo(() => {
- const labels: Record = {
- feat: { label: t("changelog.featureType"), colour: "bg-emerald-100 text-emerald-700" },
- fix: { label: t("changelog.fixType"), colour: "bg-blue-100 text-blue-700" },
- refactor: { label: t("changelog.refactorType"), colour: "bg-purple-100 text-purple-700" },
- chore: { label: t("changelog.choreType"), colour: "bg-slate-100 text-slate-700" },
- }
- return labels
- }, [t])
-
- return (
-
-
-
- {/* Header */}
-
-
-
{t("changelog.title")}
-
{t("changelog.description")}
-
-
-
- {/* Timeline */}
-
-
- {CHANGELOG_DATA.map((changelog) => (
-
- {/* Version header */}
-
-
v{changelog.version}
-
-
-
- {/* Changes list */}
-
- {changelog.entries.map((entry, idx) => {
- const typeInfo = changeTypeLabels[entry.type as ChangeTypeKey]
- return (
-
-
-
- {typeInfo.label}
-
-
-
{entry.title}
- {entry.description && (
-
{entry.description}
- )}
-
-
-
- )
- })}
-
-
- ))}
-
-
-
- )
-}
diff --git a/src/page/json-grid/index.tsx b/src/page/json-grid/index.tsx
index bbca7f9..a60a040 100644
--- a/src/page/json-grid/index.tsx
+++ b/src/page/json-grid/index.tsx
@@ -9,7 +9,6 @@ export default function JsonGrid() {
const { t } = useTranslation()
const initialData = [
- { id: 0, name: "TTY", role: "CEO", active: true },
{ id: 1, name: "Alice", role: "Developer", active: true },
{ id: 2, name: "Bob", role: "Designer", active: false },
{ id: 3, name: "Charlie", role: "Product Manager", active: true },
diff --git a/src/page/json-viewer/index.tsx b/src/page/json-viewer/index.tsx
index b5ee6f6..529a543 100644
--- a/src/page/json-viewer/index.tsx
+++ b/src/page/json-viewer/index.tsx
@@ -52,7 +52,6 @@ export default function JsonViewer() {
location: "London",
is_active: true,
staff_members: [
- { id: 100, name: "TTY", roles: ["CEO"] },
{ id: 101, name: "Alice", roles: ["Admin", "Manager"] },
{ id: 102, name: "Bob", roles: ["Developer"] },
],
diff --git a/src/router/index.tsx b/src/router/index.tsx
index c79bf3b..5aa0989 100644
--- a/src/router/index.tsx
+++ b/src/router/index.tsx
@@ -35,11 +35,7 @@ const router = createBrowserRouter(
{
path: "contact",
lazy: lazy(() => import("@/page/contact")),
- },
- {
- path: "changelog",
- lazy: lazy(() => import("@/page/changelog")),
- },
+ }
],
},
{
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
index 391fbdf..527ccb7 100644
--- a/src/vite-env.d.ts
+++ b/src/vite-env.d.ts
@@ -1,8 +1,8 @@
///
interface ImportMetaEnv {
- // todo add env properties here
+ readonly VITE_SEO_SITE_URL: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
-}
\ No newline at end of file
+}