| "use client"; |
|
|
| import { useState, useRef, useCallback } from "react"; |
|
|
| export default function UploadArea({ onUpload, loading }) { |
| const [dragOver, setDragOver] = useState(false); |
| const inputRef = useRef(null); |
|
|
| const handleFile = useCallback( |
| (file) => { |
| if (!file) return; |
| if ( |
| !file.name.endsWith(".docx") && |
| file.type !== |
| "application/vnd.openxmlformats-officedocument.wordprocessingml.document" |
| ) { |
| alert("Please upload a .docx file"); |
| return; |
| } |
| onUpload(file); |
| }, |
| [onUpload] |
| ); |
|
|
| const onDrop = useCallback( |
| (e) => { |
| e.preventDefault(); |
| setDragOver(false); |
| const file = e.dataTransfer.files[0]; |
| handleFile(file); |
| }, |
| [handleFile] |
| ); |
|
|
| const onDragOver = useCallback((e) => { |
| e.preventDefault(); |
| setDragOver(true); |
| }, []); |
|
|
| const onDragLeave = useCallback(() => { |
| setDragOver(false); |
| }, []); |
|
|
| return ( |
| <div className="flex-1 flex items-center justify-center px-6"> |
| <div className="max-w-lg w-full text-center"> |
| <div className="mb-8"> |
| <h2 |
| className="text-2xl font-semibold mb-3" |
| style={{ color: "var(--text-primary)" }} |
| > |
| Enrich your SOP headings |
| </h2> |
| <p className="text-sm leading-relaxed" style={{ color: "var(--text-secondary)" }}> |
| Upload a .docx SOP document and let AI automatically detect headings |
| that are formatted like body text. The enricher will increase their |
| font size so your parser can reliably identify sections. |
| </p> |
| </div> |
| |
| <div |
| className={`dropzone rounded-xl p-12 cursor-pointer transition-all ${dragOver ? "drag-over" : ""}`} |
| onClick={() => inputRef.current?.click()} |
| onDrop={onDrop} |
| onDragOver={onDragOver} |
| onDragLeave={onDragLeave} |
| > |
| <div className="flex flex-col items-center gap-4"> |
| <div |
| className="w-14 h-14 rounded-full flex items-center justify-center" |
| style={{ background: "var(--bg-tertiary)" }} |
| > |
| <svg |
| className="w-6 h-6" |
| style={{ color: "var(--text-secondary)" }} |
| fill="none" |
| stroke="currentColor" |
| viewBox="0 0 24 24" |
| > |
| <path |
| strokeLinecap="round" |
| strokeLinejoin="round" |
| strokeWidth={1.5} |
| d="M12 16V4m0 0L8 8m4-4l4 4M4 17v2a2 2 0 002 2h12a2 2 0 002-2v-2" |
| /> |
| </svg> |
| </div> |
| <div> |
| <p |
| className="text-sm font-medium mb-1" |
| style={{ color: "var(--text-primary)" }} |
| > |
| Drop your .docx file here, or click to browse |
| </p> |
| <p className="text-xs" style={{ color: "var(--text-muted)" }}> |
| Supports .docx files only |
| </p> |
| </div> |
| </div> |
| </div> |
| |
| <input |
| ref={inputRef} |
| type="file" |
| accept=".docx,application/vnd.openxmlformats-officedocument.wordprocessingml.document" |
| className="hidden" |
| onChange={(e) => handleFile(e.target.files[0])} |
| disabled={loading} |
| /> |
| |
| <div |
| className="mt-8 text-xs leading-relaxed" |
| style={{ color: "var(--text-muted)" }} |
| > |
| <p className="mb-2 font-medium" style={{ color: "var(--text-secondary)" }}> |
| How it works: |
| </p> |
| <div className="flex items-start gap-6 justify-center text-left"> |
| <div className="flex items-start gap-2"> |
| <span style={{ color: "var(--accent)" }}>1.</span> |
| <span>Upload your SOP .docx file</span> |
| </div> |
| <div className="flex items-start gap-2"> |
| <span style={{ color: "var(--accent)" }}>2.</span> |
| <span>AI detects headings automatically</span> |
| </div> |
| <div className="flex items-start gap-2"> |
| <span style={{ color: "var(--accent)" }}>3.</span> |
| <span>Review, adjust, and download</span> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| ); |
| } |
|
|