11"use client" ;
22
3+ import { useEffect , useState } from "react" ;
4+ import { FollowerListSchema , FollowingListSchema } from "@/lib/types" ;
35import { Github , Upload } from "lucide-react" ;
46import Link from "next/link" ;
5-
7+ import Dropzone from "react-dropzone" ;
8+ import ExtractNamesFromJson from "@/lib/extractNamesFromJson" ;
9+ import Compare from "@/lib/comparison" ;
610export default function Home ( ) {
11+ const [ followers , setFollowers ] = useState < string [ ] > ( [ ] ) ;
12+ const [ following , setFollowing ] = useState < string [ ] > ( [ ] ) ;
13+ const [ userDifference , setUserDifference ] = useState < string [ ] > ( [ ] ) ;
14+
15+ const [ hasProcessedFollowers , setHasProcessedFollowers ] = useState ( false ) ;
16+ const [ hasProcessedFollowing , setHasProcessedFollowing ] = useState ( false ) ;
17+ const [ hasProcessedDifference , setHasProcessedDifference ] = useState ( false ) ;
18+
19+ function onDrop ( acceptedFiles : File [ ] ) {
20+ acceptedFiles . forEach ( ( file ) => {
21+ const reader = new FileReader ( ) ;
22+
23+ reader . onabort = ( ) => console . log ( "file reading was aborted" ) ;
24+ reader . onerror = ( ) => console . log ( "file reading has failed" ) ;
25+ reader . onload = ( ) => {
26+ try {
27+ const input = JSON . parse ( reader . result as string ) ;
28+
29+ const followingResult = FollowingListSchema . safeParse ( input ) ;
30+ if ( followingResult . success ) {
31+ setFollowing ( ExtractNamesFromJson ( followingResult . data . relationships_following ) ) ;
32+ setHasProcessedFollowing ( true ) ;
33+ return ;
34+ }
35+
36+ const followerResult = FollowerListSchema . safeParse ( input ) ;
37+ if ( followerResult . success ) {
38+ setFollowers ( ExtractNamesFromJson ( followerResult . data ) ) ;
39+ setHasProcessedFollowers ( true ) ;
40+ return ;
41+ }
42+ } catch ( error ) {
43+ console . error ( "File is not a valid followers or following JSON:" , error ) ;
44+ }
45+ } ;
46+ reader . readAsText ( file ) ;
47+ } ) ;
48+ }
49+
50+ // Calculate Diff
51+ useEffect ( ( ) => {
52+ if ( hasProcessedFollowers && hasProcessedFollowing ) {
53+ setUserDifference ( Compare ( following , followers ) ) ;
54+ setHasProcessedDifference ( true ) ;
55+ }
56+ } , [ hasProcessedFollowers , hasProcessedFollowing , following , followers ] ) ;
57+
758 return (
859 < div className = "mx-auto container p-10" >
960 < main className = "flex items-center justify-center flex-col gap-4 px-12" >
@@ -13,13 +64,34 @@ export default function Home() {
1364 right here in your browser and are never uploaded anywhere.
1465 </ h2 >
1566
16- { /* Drop Zone */ }
17- < div className = "border-2 px-1/2 py-30 flex flex-col gap-8 items-center justify-center w-1/2 border-dashed rounded-3xl mt-12 text-lg hover:cursor-pointer" >
18- < Upload size = { 50 } > </ Upload >
19- Drag & drop your followers . json & following . json files here
20- < span > or</ span >
21- < button className = "border-1 px-4 py-2 text-lg rounded-xl hover:cursor-pointer transition hover:scale-105" > Select Files</ button >
22- </ div >
67+ { ! hasProcessedDifference ? (
68+ // Drop Zone
69+ < Dropzone onDrop = { onDrop } accept = { { "application/json" : [ ".json" ] } } >
70+ { ( { getRootProps, getInputProps } ) => (
71+ < div
72+ { ...getRootProps ( ) }
73+ className = "border-2 px-1/2 py-30 flex flex-col gap-8 items-center justify-center w-1/2 border-dashed rounded-3xl mt-12 text-lg hover:cursor-pointer"
74+ >
75+ < input { ...getInputProps ( ) } data-testid = "file-input" > </ input >
76+ < Upload size = { 50 } > </ Upload >
77+ Drag & drop your followers . json & following . json files here
78+ < span > or</ span >
79+ < button className = "border-1 px-4 py-2 text-lg rounded-xl hover:cursor-pointer transition hover:scale-105" >
80+ Select Files
81+ </ button >
82+ </ div >
83+ ) }
84+ </ Dropzone >
85+ ) : (
86+ < section >
87+ < p className = "text-2xl mb-6" > Processed!</ p >
88+ < ol >
89+ { userDifference . map ( ( userName ) => (
90+ < li key = { userName } aria-label = { userName } > { userName } </ li >
91+ ) ) }
92+ </ ol >
93+ </ section >
94+ ) }
2395
2496 < Link href = "/tutorial" className = "underline" >
2597 { " " }
0 commit comments