feat: optimised about and contact page

This commit is contained in:
siujamo
2026-01-16 09:56:48 +08:00
parent 71239b1d1b
commit 6e97243b94
2 changed files with 178 additions and 171 deletions
+63 -47
View File
@@ -1,110 +1,126 @@
/** /**
* About page component that displays information about the application. * About page component that displays information about the JSON Visualiser application.
*/ */
export default function About() { export default function About() {
return ( return (
<div className="space-y-8"> <div className="space-y-8 max-w-6xl mx-auto">
{/* Page Header */} {/* Page Header */}
<div className="text-center"> <div className="text-center">
<h1 className="text-3xl font-bold text-gray-900 sm:text-4xl"> <h1 className="text-3xl font-bold text-gray-900 sm:text-4xl">About JSON Visualiser</h1>
About This Template
</h1>
<p className="mt-4 text-lg text-gray-600"> <p className="mt-4 text-lg text-gray-600">
Learn more about the technologies and architecture behind this React Router template. A powerful, privacy-focused tool for debugging and visualising complex JSON data
structures.
</p> </p>
</div> </div>
{/* Content Sections */} {/* Content Sections */}
<div className="grid grid-cols-1 gap-8 lg:grid-cols-2"> <div className="grid grid-cols-1 gap-8 lg:grid-cols-2">
{/* Technology Stack */} {/* Technology Stack */}
<div className="bg-white shadow rounded-lg p-6"> <div className="bg-white shadow rounded-lg p-6 border border-gray-100">
<h2 className="text-xl font-semibold text-gray-900 mb-4"> <h2 className="text-xl font-semibold text-gray-900 mb-4 flex items-center">
Technology Stack <span className="mr-2">🛠</span> Technology Stack
</h2> </h2>
<ul className="space-y-3"> <ul className="space-y-3">
<li className="flex items-center"> <li className="flex items-center">
<span className="w-2 h-2 bg-blue-500 rounded-full mr-3"></span> <span className="w-2 h-2 bg-blue-500 rounded-full mr-3"></span>
<span className="text-gray-700"><strong>React 19</strong> - Latest version with modern features</span> <span className="text-gray-700">
<strong>React 19 & TS</strong> - Type-safe UI components
</span>
</li> </li>
<li className="flex items-center"> <li className="flex items-center">
<span className="w-2 h-2 bg-blue-500 rounded-full mr-3"></span> <span className="w-2 h-2 bg-blue-500 rounded-full mr-3"></span>
<span className="text-gray-700"><strong>TypeScript</strong> - Type-safe development</span> <span className="text-gray-700">
<strong>jsonpath</strong> - Robust query engine for data extraction
</span>
</li> </li>
<li className="flex items-center"> <li className="flex items-center">
<span className="w-2 h-2 bg-blue-500 rounded-full mr-3"></span> <span className="w-2 h-2 bg-blue-500 rounded-full mr-3"></span>
<span className="text-gray-700"><strong>React Router v7</strong> - Client-side routing</span> <span className="text-gray-700">
<strong>Tailwind CSS</strong> - Modern, responsive styling
</span>
</li> </li>
<li className="flex items-center"> <li className="flex items-center">
<span className="w-2 h-2 bg-blue-500 rounded-full mr-3"></span> <span className="w-2 h-2 bg-blue-500 rounded-full mr-3"></span>
<span className="text-gray-700"><strong>Tailwind CSS</strong> - Utility-first styling</span> <span className="text-gray-700">
</li> <strong>Vite</strong> - Optimised build pipeline and dev experience
<li className="flex items-center"> </span>
<span className="w-2 h-2 bg-blue-500 rounded-full mr-3"></span>
<span className="text-gray-700"><strong>Redux Toolkit</strong> - State management</span>
</li>
<li className="flex items-center">
<span className="w-2 h-2 bg-blue-500 rounded-full mr-3"></span>
<span className="text-gray-700"><strong>Vite</strong> - Fast build tool and dev server</span>
</li> </li>
</ul> </ul>
</div> </div>
{/* Features */} {/* Features */}
<div className="bg-white shadow rounded-lg p-6"> <div className="bg-white shadow rounded-lg p-6 border border-gray-100">
<h2 className="text-xl font-semibold text-gray-900 mb-4"> <h2 className="text-xl font-semibold text-gray-900 mb-4 flex items-center">
Key Features <span className="mr-2">🚀</span> Key Features
</h2> </h2>
<ul className="space-y-3"> <ul className="space-y-3">
<li className="flex items-center"> <li className="flex items-center">
<span className="w-2 h-2 bg-green-500 rounded-full mr-3"></span> <span className="w-2 h-2 bg-green-500 rounded-full mr-3"></span>
<span className="text-gray-700">Modern React Router implementation</span> <span className="text-gray-700">
Interactive <strong>collapsible</strong> tree navigation
</span>
</li> </li>
<li className="flex items-center"> <li className="flex items-center">
<span className="w-2 h-2 bg-green-500 rounded-full mr-3"></span> <span className="w-2 h-2 bg-green-500 rounded-full mr-3"></span>
<span className="text-gray-700">Protected routes with authentication</span> <span className="text-gray-700">
Real-time JSONPath field <strong>highlighting</strong>
</span>
</li> </li>
<li className="flex items-center"> <li className="flex items-center">
<span className="w-2 h-2 bg-green-500 rounded-full mr-3"></span> <span className="w-2 h-2 bg-green-500 rounded-full mr-3"></span>
<span className="text-gray-700">Error boundary and error pages</span> <span className="text-gray-700">One-click copy for matched results</span>
</li> </li>
<li className="flex items-center"> <li className="flex items-center">
<span className="w-2 h-2 bg-green-500 rounded-full mr-3"></span> <span className="w-2 h-2 bg-green-500 rounded-full mr-3"></span>
<span className="text-gray-700">Responsive design with Tailwind</span> <span className="text-gray-700">Zero-latency local processing</span>
</li>
<li className="flex items-center">
<span className="w-2 h-2 bg-green-500 rounded-full mr-3"></span>
<span className="text-gray-700">TypeScript for type safety</span>
</li>
<li className="flex items-center">
<span className="w-2 h-2 bg-green-500 rounded-full mr-3"></span>
<span className="text-gray-700">ESLint and Prettier configuration</span>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
{/* Privacy Commitment */}
<div className="bg-indigo-50 border border-indigo-100 rounded-lg p-6 text-indigo-900">
<h2 className="text-xl font-semibold mb-3 flex items-center">
<span className="mr-2">🔒</span> Privacy & Data Security
</h2>
<p className="leading-relaxed">
We believe that your data belongs to you. This application is designed as a{" "}
<strong>purely client-side tool</strong>. All JSON parsing, path evaluation, and visual
rendering are performed locally within your browser. No data is ever uploaded to any
server, ensuring that sensitive configuration or user data remains entirely private.
</p>
</div>
{/* Architecture Overview */} {/* Architecture Overview */}
<div className="bg-white shadow rounded-lg p-6"> <div className="bg-white shadow rounded-lg p-6">
<h2 className="text-xl font-semibold text-gray-900 mb-4"> <h2 className="text-xl font-semibold text-gray-900 mb-4 flex items-center">
Architecture Overview <span className="mr-2">🏗</span> Architecture Overview
</h2> </h2>
<div className="prose max-w-none text-gray-700"> <div className="prose max-w-none text-gray-700">
<p className="mb-4"> <p className="mb-4">
This template follows modern React development practices with a clear separation of concerns: The application follows a modular React architecture focused on performance and
maintainability:
</p> </p>
<ul className="list-disc list-inside space-y-2 mb-4"> <ul className="list-disc list-inside space-y-2 mb-4">
<li><strong>Components:</strong> Reusable UI components organised by feature</li> <li>
<li><strong>Pages:</strong> Route-level components that represent different views</li> <strong>Recursive Renderer:</strong> A high-performance component tree that handles
<li><strong>Layouts:</strong> Wrapper components that provide consistent structure</li> massive JSON objects without blocking the main thread.
<li><strong>Store:</strong> Redux Toolkit slices for state management</li> </li>
<li><strong>Router:</strong> Centralised routing configuration</li> <li>
<strong>JSONPath Integration:</strong> Standardised path evaluation using the{" "}
<code>jsonpath</code> library, ensuring cross-platform query compatibility.
</li>
<li>
<strong>State Management:</strong> Efficient use of React hooks and useMemo to ensure
real-time UI updates during text entry.
</li>
</ul> </ul>
<p> <p>
The routing system uses React Router&apos;s latest data router approach with <code>createBrowserRouter</code>, Hosted on Vercel, this visualiser leverages modern edge deployment whilst strictly
providing better performance and developer experience compared to the legacy BrowserRouter approach. adhering to the local-first data processing principle.
</p> </p>
</div> </div>
</div> </div>
</div> </div>
) )
} }
+115 -124
View File
@@ -1,130 +1,92 @@
import React from "react" import React from "react"
/** /**
* Contact page component that displays contact information and a contact form. * Contact page component that encourages manual GitHub Issue submission.
*/ */
export default function Contact() { export default function Contact() {
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { const owner = "onixbyte"
const repo = "json-visualiser"
const handleRedirect = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault() e.preventDefault()
// Handle form submission logic here const formData = new FormData(e.currentTarget)
alert("Thank you for your message! This is a demo form.")
const subject = formData.get("subject") as string
const name = formData.get("name") as string
const email = formData.get("email") as string
const message = formData.get("message") as string
const type = formData.get("type") as string
// Construct a professional body template for the GitHub issue
const issueBody = `
### Description
${message}
---
*Generated via JSON Visualiser Contact Page*
`.trim()
const githubUrl = `https://github.com/${owner}/${repo}/issues/new?title=${encodeURIComponent(
`[${type == "help wanted" ? "General Enquiry" : (type == "enhancement" ? "Feature request" : "Bug")}] ${subject}`
)}&body=${encodeURIComponent(issueBody)}&labels=${type}`
// Open in a new tab so they don't lose their place on your site
window.open(githubUrl, "_blank", "noopener,noreferrer")
} }
return ( return (
<div className="space-y-8"> <div className="max-w-5xl mx-auto py-12 px-4 sm:px-6">
{/* Page Header */} {/* Header */}
<div className="text-center"> <div className="text-center mb-12">
<h1 className="text-3xl font-bold text-gray-900 sm:text-4xl"> <h1 className="text-3xl font-bold text-gray-900 sm:text-4xl">Get in Touch</h1>
Get in Touch
</h1>
<p className="mt-4 text-lg text-gray-600"> <p className="mt-4 text-lg text-gray-600">
Have questions about this template? We&apos;d love to hear from you. The best way to reach us is via our GitHub repository.
</p> </p>
</div> </div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8"> <div className="grid grid-cols-1 md:grid-cols-2 gap-12 items-start">
{/* Contact Information */} {/* Left Side: Information */}
<div className="bg-white shadow rounded-lg p-6"> <div className="space-y-8">
<h2 className="text-xl font-semibold text-gray-900 mb-6"> <section>
Contact Information <h2 className="text-xl font-semibold text-gray-900 mb-4 flex items-center">
</h2> <span className="mr-2">🤝</span> Why GitHub Issues?
</h2>
<div className="space-y-4"> <p className="text-gray-600 leading-relaxed">
{/* Email */} We use GitHub to track all bug reports and feature requests. This ensures our
<div className="flex items-center"> development process remains **transparent** and that your feedback is properly
<div className="flex-shrink-0"> prioritised by the community.
<svg className="h-6 w-6 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"> </p>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 4.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" /> </section>
</svg>
</div>
<div className="ml-3">
<p className="text-sm font-medium text-gray-900">Email</p>
<p className="text-sm text-gray-600">zihlu.wang@outlook.com</p>
</div>
</div>
{/* GitHub */} <section className="bg-blue-50 border border-blue-100 p-6 rounded-2xl">
<div className="flex items-center"> <h3 className="text-blue-900 font-bold mb-2">How it works:</h3>
<div className="flex-shrink-0"> <ol className="list-decimal list-inside text-blue-800 text-sm space-y-2">
<svg className="h-6 w-6 text-gray-400" fill="currentColor" viewBox="0 0 24 24"> <li>Fill in the enquiry details in the form provided.</li>
<path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" /> <li>
</svg> Click <strong>"Prepare GitHub Issue"</strong>.
</div> </li>
<div className="ml-3"> <li>You will be redirected to GitHub with the data pre-filled.</li>
<p className="text-sm font-medium text-gray-900"><a href="https://github.com/onixbyte/react-template">GitHub</a></p> <li>
<p className="text-sm text-gray-600">github.com/onixbyte/react-template</p> Simply hit <strong>"Submit new issue"</strong> on their site.
</div> </li>
</div> </ol>
</section>
{/* Documentation */} <div className="pt-4 border-t border-gray-100">
<div className="flex items-center"> <p className="text-sm text-gray-500 italic">
<div className="flex-shrink-0"> Alternatively, you can email us directly at: <br />
<svg className="h-6 w-6 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <a
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /> href="mailto:real@zihluwang.me"
</svg> className="text-blue-600 font-medium hover:underline">
</div> real@zihluwang.me
<div className="ml-3">
<p className="text-sm font-medium text-gray-900">Documentation</p>
<p className="text-sm text-gray-600">Check the README.md file</p>
</div>
</div>
</div>
{/* Quick Links */}
<div className="mt-8">
<h3 className="text-lg font-medium text-gray-900 mb-4">Quick Links</h3>
<div className="space-y-2">
<a href="https://reactrouter.com" target="_blank" rel="noopener noreferrer" className="block text-blue-600 hover:text-blue-800 text-sm">
React Router Documentation
</a> </a>
<a href="https://tailwindcss.com" target="_blank" rel="noopener noreferrer" className="block text-blue-600 hover:text-blue-800 text-sm"> </p>
Tailwind CSS Documentation
</a>
<a href="https://vitejs.dev" target="_blank" rel="noopener noreferrer" className="block text-blue-600 hover:text-blue-800 text-sm">
Vite Documentation
</a>
</div>
</div> </div>
</div> </div>
{/* Contact Form */} {/* Right Side: Form */}
<div className="bg-white shadow rounded-lg p-6"> <div className="bg-white shadow-xl shadow-gray-200/50 border border-gray-100 rounded-2xl p-8">
<h2 className="text-xl font-semibold text-gray-900 mb-6"> <form onSubmit={handleRedirect} className="space-y-5">
Send us a Message
</h2>
<form onSubmit={handleSubmit} className="space-y-4">
{/* Name */}
<div>
<label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-1">
Name
</label>
<input
type="text"
id="name"
name="name"
required
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="Your full name"
/>
</div>
{/* Email */}
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1">
Email
</label>
<input
type="email"
id="email"
name="email"
required
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="your.email@example.com"
/>
</div>
{/* Subject */}
<div> <div>
<label htmlFor="subject" className="block text-sm font-medium text-gray-700 mb-1"> <label htmlFor="subject" className="block text-sm font-medium text-gray-700 mb-1">
Subject Subject
@@ -134,38 +96,67 @@ export default function Contact() {
id="subject" id="subject"
name="subject" name="subject"
required required
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:bg-white outline-none transition-all"
placeholder="What is this about?" placeholder="Bug report / Feature request"
/> />
</div> </div>
{/* Message */} <div>
<label
htmlFor="type"
className="block text-sm font-semibold text-gray-700 mb-1.5 ml-1">
Enquiry Type
</label>
<div className="relative group">
<select
id="type"
name="type"
required
className="w-full appearance-none px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl text-gray-700 text-sm cursor-pointer transition-all duration-200 hover:border-gray-300 hover:bg-gray-100/50 focus:ring-4 focus:ring-indigo-500/10 focus:border-indigo-500 focus:bg-white outline-none">
<option value="help wanted">General Enquiry</option>
<option value="enhancement">Feature Request</option>
<option value="bug">Bug</option>
</select>
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-3 text-gray-400 group-hover:text-gray-600 transition-colors">
<svg
className="h-4 w-4 fill-current"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20">
<path d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" />
</svg>
</div>
</div>
<p className="mt-2 ml-1 text-[11px] text-gray-400">
Selecting a type helps us categorise and prioritise your issue.
</p>
</div>
<div> <div>
<label htmlFor="message" className="block text-sm font-medium text-gray-700 mb-1"> <label htmlFor="message" className="block text-sm font-medium text-gray-700 mb-1">
Message Message Details
</label> </label>
<textarea <textarea
id="message" id="message"
name="message" name="message"
rows={4} rows={4}
required required
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:bg-white outline-none transition-all resize-none"
placeholder="Tell us more about your question or feedback..." placeholder="Describe your enquiry here..."
/> />
</div> </div>
{/* Submit Button */} <button
<div> type="submit"
<button className="w-full flex items-center justify-center py-3 px-4 rounded-xl text-white font-bold bg-gray-900 hover:bg-gray-800 transition-all shadow-lg">
type="submit" <svg className="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 21.795 24 17.297 24 12.017c0-6.627-5.373-12-12-12" />
> </svg>
Send Message Prepare GitHub Issue
</button> </button>
</div>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
) )
} }