Skip to content

Commit 4b2b715

Browse files
author
minhnq
committed
feat: Add functionality to import JSON from a file.
1 parent b94afd3 commit 4b2b715

1 file changed

Lines changed: 50 additions & 1 deletion

File tree

src/app/json/page.tsx

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { useState, useEffect, useCallback, useRef } from 'react';
44
import Navigation from '@/components/Navigation';
55
import Toast, { useToast } from '@/components/Toast';
6-
import { CopyIcon, CheckIcon, CodeIcon, LinkIcon, ClockIcon, TrashIcon, ExternalLinkIcon } from '@/components/Icons';
6+
import { CopyIcon, CheckIcon, CodeIcon, LinkIcon, ClockIcon, TrashIcon, ExternalLinkIcon, UploadIcon } from '@/components/Icons';
77
import styles from './page.module.css';
88

99
const STORAGE_KEY = 'json-bins-history';
@@ -68,6 +68,7 @@ export default function JsonServerPage() {
6868
const [history, setHistory] = useState<JsonBin[]>([]);
6969
const [copiedField, setCopiedField] = useState<string | null>(null);
7070
const textareaRef = useRef<HTMLTextAreaElement>(null);
71+
const fileInputRef = useRef<HTMLInputElement>(null);
7172
const { toasts, addToast, removeToast } = useToast();
7273

7374
// Load history from localStorage
@@ -172,6 +173,39 @@ export default function JsonServerPage() {
172173
setResult(null);
173174
};
174175

176+
const handleImportClick = () => {
177+
fileInputRef.current?.click();
178+
};
179+
180+
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
181+
const file = event.target.files?.[0];
182+
if (!file) return;
183+
184+
const reader = new FileReader();
185+
reader.onload = (e) => {
186+
const content = e.target?.result as string;
187+
try {
188+
// Try parsing to verify it's valid JSON, but allow editing even if slightly off (though requirements say valid json)
189+
// Actually the tool validates on input change, so we just set the text.
190+
// We'll throw if it's not even text.
191+
192+
// Let's verify it's valid JSON for better UX before setting
193+
JSON.parse(content);
194+
setJsonInput(content);
195+
addToast('JSON imported successfully', 'success');
196+
} catch (error) {
197+
addToast('Invalid JSON file', 'error');
198+
}
199+
};
200+
reader.onerror = () => {
201+
addToast('Error reading file', 'error');
202+
};
203+
reader.readAsText(file);
204+
205+
// Reset input so same file can be selected again
206+
event.target.value = '';
207+
};
208+
175209
const handleCopy = async (text: string, field: string) => {
176210
await navigator.clipboard.writeText(text);
177211
setCopiedField(field);
@@ -230,6 +264,21 @@ export default function JsonServerPage() {
230264
{/* Toolbar */}
231265
<div className={styles.toolbar}>
232266
<div className={styles.toolbarLeft}>
267+
<input
268+
type="file"
269+
ref={fileInputRef}
270+
onChange={handleFileChange}
271+
accept="application/json"
272+
style={{ display: 'none' }}
273+
/>
274+
<button
275+
onClick={handleImportClick}
276+
className={styles.toolButton}
277+
title="Import JSON file"
278+
>
279+
<UploadIcon size={16} style={{ marginRight: '6px' }} />
280+
Import
281+
</button>
233282
<button
234283
onClick={handleFormat}
235284
disabled={!validation.valid}

0 commit comments

Comments
 (0)