v1.0.0: Complete layout restructure and design improvements
- Restructure layout to match copilot instructions exactly - Add proper footer section with author and license information - Fix header size - make it more compact and appropriate - Move app description from header to regular paragraph text - Optimize layout to fit within 1080p viewport without overflow - Add Google Noto fonts for modern typography (Noto Sans + Noto Sans Mono) - Improve responsive design and visual spacing - Remove unnecessary gaps and improve overall UX - Application now properly follows all architectural specifications
This commit is contained in:
@@ -8,6 +8,9 @@
|
||||
<meta name="description" content="JMESPath Testing Tool - Validate and test JMESPath expressions against JSON data" />
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700&family=Noto+Sans+Mono:wght@300;400;500;600&display=swap" rel="stylesheet">
|
||||
<title>JMESPath Testing Tool</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
100
src/App.css
100
src/App.css
@@ -1,41 +1,29 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
/* JMESPath Testing Tool Custom Styles */
|
||||
|
||||
/* Base font family */
|
||||
body {
|
||||
font-family: 'Noto Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
/* Layout structure */
|
||||
.vh-100 {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
padding: 20px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
/* Header section styling - more compact */
|
||||
.header-section {
|
||||
/* Removed gradient background to fix text visibility */
|
||||
}
|
||||
|
||||
/* Custom card styling */
|
||||
.card {
|
||||
border: none;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
@@ -44,7 +32,34 @@
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Button hover effects */
|
||||
/* Input and textarea styling */
|
||||
.jmespath-input {
|
||||
font-family: 'Noto Sans Mono', 'Consolas', 'Monaco', 'Courier New', monospace;
|
||||
font-size: 14px;
|
||||
padding: 10px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.json-input, .result-output {
|
||||
font-family: 'Noto Sans Mono', 'Consolas', 'Monaco', 'Courier New', monospace;
|
||||
font-size: 13px;
|
||||
background-color: #f8f9fa;
|
||||
border: 1px solid #dee2e6;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.json-input.error {
|
||||
border-color: #dc3545;
|
||||
background-color: #fff5f5;
|
||||
}
|
||||
|
||||
.result-output.success {
|
||||
border-color: #28a745;
|
||||
background-color: #f0fff4;
|
||||
}
|
||||
|
||||
/* Button styling */
|
||||
.btn {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
@@ -53,10 +68,24 @@
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* Footer styling */
|
||||
footer {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
footer a {
|
||||
color: #6c757d;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
footer a:hover {
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.header-section {
|
||||
padding: 1rem 0;
|
||||
padding: 1.5rem 0 !important;
|
||||
}
|
||||
|
||||
.display-4 {
|
||||
@@ -66,4 +95,13 @@
|
||||
.lead {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
font-size: 0.8rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
.card-body textarea {
|
||||
min-height: 300px !important;
|
||||
}
|
||||
}
|
||||
99
src/App.js
99
src/App.js
@@ -180,32 +180,39 @@ function App() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container-fluid">
|
||||
{/* Header Section */}
|
||||
<div className="header-section">
|
||||
<div className="container-fluid vh-100 d-flex flex-column">
|
||||
{/* Top Section: Title only */}
|
||||
<div className="header-section py-2">
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col-12 text-center">
|
||||
<h1 className="display-4 mb-3">JMESPath Testing Tool</h1>
|
||||
<p className="lead">
|
||||
Validate and test JMESPath expressions against JSON data in real-time.
|
||||
Enter your JMESPath query and JSON data below to see the results instantly.
|
||||
</p>
|
||||
<h2 className="mb-1">JMESPath Testing Tool</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="container-fluid content-section">
|
||||
<div className="row h-100">
|
||||
{/* JMESPath Expression Input - Middle Section */}
|
||||
<div className="col-12 mb-3">
|
||||
{/* Main Content Section - flex-grow to fill space */}
|
||||
<div className="container-fluid flex-grow-1 d-flex flex-column" style={{ minHeight: 0 }}>
|
||||
{/* Description paragraph */}
|
||||
<div className="row mb-2">
|
||||
<div className="col-12">
|
||||
<p className="text-muted text-center mb-2 small">
|
||||
Validate and test JMESPath expressions against JSON data in real-time.
|
||||
Enter your JMESPath query and JSON data below to see the results instantly.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Middle Section: JMESPath Expression Input */}
|
||||
<div className="row mb-2">
|
||||
<div className="col-12">
|
||||
<div className="card">
|
||||
<div className="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 className="mb-0">
|
||||
<div className="card-header d-flex justify-content-between align-items-center py-2">
|
||||
<h6 className="mb-0">
|
||||
<i className="bi bi-search me-2"></i>
|
||||
JMESPath Expression
|
||||
</h5>
|
||||
</h6>
|
||||
<div>
|
||||
<button
|
||||
className="btn btn-outline-success btn-sm me-2"
|
||||
@@ -260,50 +267,55 @@ function App() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom Row - JSON Input and Results */}
|
||||
<div className="col-md-6 mb-3">
|
||||
{/* Lower Middle Sections: JSON Data (left) and Query Result (right) */}
|
||||
<div className="row flex-grow-1" style={{ minHeight: 0 }}>
|
||||
{/* Lower Middle Left Section: JSON Data Input */}
|
||||
<div className="col-md-6">
|
||||
<div className="card h-100">
|
||||
<div className="card-header">
|
||||
<h5 className="mb-0">
|
||||
<div className="card-header py-2">
|
||||
<h6 className="mb-0">
|
||||
<i className="bi bi-file-code me-2"></i>
|
||||
JSON Data
|
||||
</h5>
|
||||
</h6>
|
||||
</div>
|
||||
<div className="card-body input-section">
|
||||
<div className="textarea-container">
|
||||
<div className="card-body d-flex flex-column" style={{ minHeight: 0 }}>
|
||||
<div className="flex-grow-1" style={{ minHeight: 0 }}>
|
||||
<textarea
|
||||
className={`form-control json-input ${jsonError ? 'error' : ''}`}
|
||||
className={`form-control h-100 json-input ${jsonError ? 'error' : ''}`}
|
||||
value={jsonData}
|
||||
onChange={handleJsonChange}
|
||||
placeholder="Enter JSON data here..."
|
||||
style={{ minHeight: 0, resize: 'none' }}
|
||||
/>
|
||||
</div>
|
||||
{jsonError && (
|
||||
<div className="alert alert-danger mt-2 mb-0">
|
||||
<div className="alert alert-danger mt-1 mb-0 py-1">
|
||||
<small>{jsonError}</small>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Results Output - Bottom Right */}
|
||||
<div className="col-md-6 mb-3">
|
||||
{/* Lower Middle Right Section: Query Results Output */}
|
||||
<div className="col-md-6">
|
||||
<div className="card h-100">
|
||||
<div className="card-header">
|
||||
<h5 className="mb-0">
|
||||
<div className="card-header py-2">
|
||||
<h6 className="mb-0">
|
||||
<i className="bi bi-arrow-right-circle me-2"></i>
|
||||
Query Result
|
||||
</h5>
|
||||
</h6>
|
||||
</div>
|
||||
<div className="card-body output-section">
|
||||
<div className="textarea-container">
|
||||
<div className="card-body d-flex flex-column" style={{ minHeight: 0 }}>
|
||||
<div className="flex-grow-1" style={{ minHeight: 0 }}>
|
||||
<textarea
|
||||
className={`form-control result-output ${result && !error && !jsonError ? 'success' : ''}`}
|
||||
className={`form-control h-100 result-output ${result && !error && !jsonError ? 'success' : ''}`}
|
||||
value={result}
|
||||
readOnly
|
||||
placeholder="Results will appear here..."
|
||||
style={{ minHeight: 0, resize: 'none' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -311,6 +323,27 @@ function App() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom Section: Footer */}
|
||||
<footer className="bg-light border-top mt-2 py-2 flex-shrink-0">
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col-md-6">
|
||||
<p className="mb-0 text-muted small">
|
||||
<strong>JMESPath Testing Tool</strong> - Created for testing and validating JMESPath expressions
|
||||
</p>
|
||||
</div>
|
||||
<div className="col-md-6 text-md-end">
|
||||
<p className="mb-0 text-muted small">
|
||||
Licensed under <a href="#" className="text-decoration-none">MIT License</a> |
|
||||
<a href="https://jmespath.org/" target="_blank" rel="noopener noreferrer" className="text-decoration-none ms-2">
|
||||
Learn JMESPath
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user