1+ /* eslint-disable @next/next/no-img-element */
12"use client" ;
23
34import Fieldset from "@/components/fieldset" ;
@@ -19,6 +20,9 @@ import TextareaAutosize from "react-textarea-autosize";
1920import { createChat , getNextCompletionStreamPromise } from "./actions" ;
2021import { Context } from "./providers" ;
2122import Header from "@/components/header" ;
23+ import { useS3Upload } from "next-s3-upload" ;
24+ import UploadIcon from "@/components/icons/upload-icon" ;
25+ import { XCircleIcon } from "@heroicons/react/20/solid" ;
2226
2327const MODELS = [
2428 {
@@ -84,8 +88,22 @@ export default function Home() {
8488 const [ prompt , setPrompt ] = useState ( "" ) ;
8589 const [ model , setModel ] = useState ( MODELS [ 0 ] . value ) ;
8690 const [ quality , setQuality ] = useState ( "high" ) ;
91+ const [ imageUrl , setImageUrl ] = useState < string | undefined > (
92+ "https://napkinsdev.s3.us-east-1.amazonaws.com/next-s3-uploads/37ba6e68-3ddf-412a-9507-c52fbdee1ace/CleanShot-2025-01-07-at-10.31.33-2x.png" ,
93+ ) ;
8794
8895 const selectedModel = MODELS . find ( ( m ) => m . value === model ) ;
96+ const { uploadToS3 } = useS3Upload ( ) ;
97+
98+ const handleFileChange = async ( event : any ) => {
99+ let file = event . target . files [ 0 ] ;
100+ let objectUrl = URL . createObjectURL ( file ) ;
101+ setImageUrl ( objectUrl ) ;
102+ const { url } = await uploadToS3 ( file ) ;
103+ setImageUrl ( url ) ;
104+ } ;
105+
106+ console . log ( { imageUrl } ) ;
89107
90108 return (
91109 < div className = "relative flex grow flex-col" >
@@ -147,6 +165,20 @@ export default function Home() {
147165 } }
148166 >
149167 < Fieldset >
168+ { imageUrl && (
169+ < div className = "relative bg-gray-500" >
170+ < div className = "rounded-xl" >
171+ < img
172+ alt = "screenshot"
173+ src = { imageUrl }
174+ className = "group relative mb-2 h-16 w-[68px] rounded"
175+ />
176+ </ div >
177+ < button className = "absolute -right-3 -top-4 left-14 z-10 size-5 rounded-full bg-white text-gray-900 hover:text-gray-500" >
178+ < XCircleIcon onClick = { ( ) => setImageUrl ( "" ) } />
179+ </ button >
180+ </ div >
181+ ) }
150182 < div className = "relative flex rounded-xl border-4 border-gray-300 bg-white pb-10" >
151183 < TextareaAutosize
152184 placeholder = "Build me a budgeting app..."
@@ -209,7 +241,7 @@ export default function Home() {
209241
210242 < div className = "h-4 w-px bg-gray-200 max-sm:hidden" />
211243
212- < label className = "inline-flex items-center gap-2 text-sm text-gray-400" >
244+ { /* <label className="inline-flex items-center gap-2 text-sm text-gray-400">
213245 <span className="sm:hidden">shad</span>
214246 <span className="max-sm:hidden">
215247 shadcn<span className="font-medium">/</span>ui
@@ -219,7 +251,7 @@ export default function Home() {
219251 </Switch>
220252 </label>
221253
222- < div className = "h-4 w-px bg-gray-200 max-sm:hidden" />
254+ <div className="h-4 w-px bg-gray-200 max-sm:hidden" /> */ }
223255
224256 < Select . Root
225257 name = "quality"
@@ -246,7 +278,10 @@ export default function Home() {
246278 < Select . Viewport className = "space-y-1 p-2" >
247279 { [
248280 { value : "low" , label : "Low quality [faster]" } ,
249- { value : "high" , label : "High quality [slower]" } ,
281+ {
282+ value : "high" ,
283+ label : "High quality [slower]" ,
284+ } ,
250285 ] . map ( ( q ) => (
251286 < Select . Item
252287 key = { q . value }
@@ -267,10 +302,31 @@ export default function Home() {
267302 </ Select . Content >
268303 </ Select . Portal >
269304 </ Select . Root >
305+ < div className = "h-4 w-px bg-gray-200 max-sm:hidden" />
306+ < div >
307+ < label
308+ htmlFor = "fileInput"
309+ className = "flex cursor-pointer gap-2 text-sm text-gray-400 hover:underline"
310+ >
311+ < div className = "flex size-6 items-center justify-center rounded bg-blue-400" >
312+ < UploadIcon className = "size-4" />
313+ </ div >
314+ < div className = "flex items-center justify-center" >
315+ Attach
316+ </ div >
317+ </ label >
318+ < input
319+ id = "fileInput"
320+ type = "file"
321+ onChange = { handleFileChange }
322+ className = "hidden"
323+ />
324+ </ div >
270325 </ div >
271326
272327 < div className = "relative flex shrink-0 has-[:disabled]:opacity-50" >
273- < div className = "pointer-events-none absolute inset-0 -bottom-[1px] rounded bg-blue-700" />
328+ < div className = "pointer-events-none absolute inset-0 -bottom-[1px] rounded bg-blue-500" />
329+
274330 < LoadingButton
275331 className = "relative inline-flex size-6 items-center justify-center rounded bg-blue-500 font-medium text-white shadow-lg outline-blue-300 hover:bg-blue-500/75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
276332 type = "submit"
@@ -279,7 +335,6 @@ export default function Home() {
279335 </ LoadingButton >
280336 </ div >
281337 </ div >
282-
283338 < LoadingMessage />
284339 </ div >
285340 < div className = "mt-4 flex w-full flex-wrap justify-center gap-3" >
0 commit comments