diff --git a/src/app.css b/src/app.css index 9186464..5680de5 100644 --- a/src/app.css +++ b/src/app.css @@ -66,21 +66,49 @@ h1 { .query-section textarea { margin-bottom: 1.5rem; margin-top: -1.5rem; - border: 1px solid #00411a; - border-radius: 8px; font-size: 1.15rem; padding: 1.1rem; background: #f7f7f7; color: #067800; transition: border 0.2s; - height: 160px; min-height: 160px; - max-height: 160px; - resize: none; + max-height: 350px; + resize: vertical; + overflow-y: auto; + border: 1.5px solid #bdbdbd; + border-radius: 8px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); + overflow-x: hidden; + white-space: pre-wrap; +} + +/* --- Unified custom scrollbar styles for textarea and JSON preview --- */ +.query-section textarea, +.json-preview { + scrollbar-width: thin; + /* Firefox */ + scrollbar-color: #009624 #e0e0e0; + /* Firefox */ + overflow-x: hidden; + white-space: pre-wrap; } -.query-section textarea:focus { - border: 1.5px solid var(--primary-green); +.query-section textarea::-webkit-scrollbar, +.json-preview::-webkit-scrollbar { + width: 10px; + background: #e0e0e0; + border-radius: 6px; +} + +.query-section textarea::-webkit-scrollbar-thumb, +.json-preview::-webkit-scrollbar-thumb { + background: #009624; + border-radius: 6px; +} + +.query-section textarea:focus, +.json-preview:focus { + border-color: #009624; outline: none; } @@ -288,13 +316,18 @@ tr:nth-child(even) td { } .json-preview { - background: #f5f5f5; - padding: 1rem; - border-radius: 6px; - overflow-x: auto; font-family: "Fira Mono", monospace; font-size: 0.9rem; margin: 1rem 0; + max-height: 350px; + padding: 1.1rem; + background: #f7f7f7; + color: #067800; + border: 1.5px solid #bdbdbd; + border-radius: 8px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); + overflow-x: hidden; + white-space: pre-wrap; } .preview-note { @@ -383,28 +416,11 @@ p { outline: none; } -.preview-section { - margin-top: 1.5rem; - background: var(--card-bg); - border-radius: 8px; - padding: 1.5rem; - color: #222; -} - -.json-preview { - background: #f5f5f5; - padding: 1rem; - border-radius: 6px; - overflow-x: auto; - font-family: "Fira Mono", monospace; - font-size: 0.9rem; - margin: 1rem 0; -} - -.preview-note { - color: #666; - font-size: 0.9rem; - margin: 0; +/* Ensure Preview title is green */ +.preview-section h2 { + color: #067800; + margin-bottom: 1rem; + margin-top: -2px; } .table-container { @@ -427,4 +443,136 @@ h3 { p { margin: 0.5rem 0; color: var(--text-light); +} + +.sample-suggestions { + margin: 1.2rem 0 2rem 0; + display: flex; + align-items: center; + gap: 0.7rem; + flex-wrap: wrap; + padding: 1rem 1.5rem; + background: rgba(0, 150, 36, 0.07); + border: 1.5px solid #b9f6ca; + border-radius: 12px; + box-shadow: 0 2px 8px rgba(0, 200, 83, 0.06); + justify-content: flex-start; +} + +.sample-suggestions span { + font-weight: 600; + font-size: 1.08rem; + margin-right: 0.5rem; +} + +.sample-suggestions button { + background: #e0e0e0; + color: #067800; + border: 2px solid #009624; + border-radius: 20px; + padding: 0.5rem 1.4rem; + font-size: 1.08rem; + font-weight: 700; + cursor: pointer; + transition: background 0.2s, box-shadow 0.2s, border-color 0.2s; + box-shadow: 0 1px 4px rgba(0, 200, 83, 0.09); + outline: none; +} + +.sample-suggestions button:hover { + background: #b9f6ca; + border-color: #00c853; + box-shadow: 0 2px 8px rgba(0, 200, 83, 0.18); +} + +.json-input-section .sample-suggestions span { + color: #fff; +} + +.sample-suggestions span { + color: #222; +} + +.raw-json-section h2 { + margin-top: -2px; + color: #067800; +} + +.app-summary-card { + background: #f7f7f7; + border-radius: 10px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); + padding: 1.2rem 2rem 1.2rem 2rem; + margin-bottom: 2.2rem; + border: 1.5px solid #b9f6ca; + width: 100%; + box-sizing: border-box; +} + +.app-summary { + color: #067800; + font-size: 1.13rem; + margin-bottom: 0.7rem; + text-align: center; +} + +.app-guide { + color: #222; + font-size: 1.05rem; + margin: 0; + padding-left: 1.2rem; + text-align: left; +} + +.app-guide li { + margin-bottom: 0.3rem; +} + +@media (max-width: 600px) { + .container { + padding: 0.7rem; + } + + .app-summary-card { + padding: 0.7rem 0.7rem 0.7rem 0.7rem; + font-size: 0.98rem; + } + + .app-summary { + font-size: 1rem; + } + + .app-guide { + font-size: 0.97rem; + padding-left: 0.7rem; + } + + .sample-suggestions { + padding: 0.7rem; + flex-direction: column; + align-items: flex-start; + gap: 0.5rem; + } + + .sample-suggestions button { + width: 100%; + min-width: 0; + text-align: left; + font-size: 1rem; + padding: 0.5rem 0.7rem; + } + + .query-actions { + flex-direction: column; + align-items: stretch; + gap: 0.7rem; + } + + .query-actions button, + .query-actions .clear-btn { + width: 100%; + min-width: 0; + box-sizing: border-box; + margin: 0; + } } \ No newline at end of file diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index fbe9e2c..ea51fb7 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -17,6 +17,35 @@ let previewData: string = ""; let inputMode: "file" | "raw" = "file"; + // Sample data for suggestions + const sampleJsons = [ + { + label: "US States Population", + value: `[ + { "state": "California", "region": "West", "pop": 39538223, "pop_male": 19453769, "pop_female": 20084454 }, + { "state": "Texas", "region": "South", "pop": 29145505, "pop_male": 14358470, "pop_female": 14787035 }, + { "state": "Florida", "region": "South", "pop": 21538187, "pop_male": 10470577, "pop_female": 11067610 } +]`, + }, + // Add more samples if you want + ]; + + const sampleSqls = [ + { + label: "All States", + value: "SELECT * FROM table;", + }, + { + label: "States with pop > 20M", + value: "SELECT state, pop FROM table WHERE pop > 20000000;", + }, + { + label: "States in the South", + value: "SELECT state FROM table WHERE region = 'South';", + }, + // Add more samples if you want + ]; + function saveHistory() { sessionStorage.setItem("queryHistory", JSON.stringify(history)); sessionStorage.setItem("queryHistoryNextId", String(nextId)); @@ -34,7 +63,7 @@ try { data = JSON.parse(input); jsonError = null; - previewData = JSON.stringify(data.slice(0, 3), null, 2); + previewData = JSON.stringify(data, null, 2); } catch (err) { jsonError = "Invalid JSON input."; data = []; @@ -129,6 +158,27 @@

SQL Query Parser

+
+

+ Welcome! This tool lets you quickly explore and analyze + your own JSON data using familiar SQL queries right in your browser, + with no setup or database required. +

+
    +
  1. + Paste or upload your JSON data + below. +
  2. +
  3. Preview your data instantly.
  4. +
  5. + Write an SQL query and click + Execute Query. +
  6. +
  7. + See results, errors, and your query history—all in one place! +
  8. +
+
@@ -148,6 +198,22 @@
+ +
+ Try sample JSON: + {#each sampleJsons as sample} + + {/each} +
+ {#if inputMode === "file"}
{:else}
+

JSON Input