From 3f42c810927d153e368811e816829aa24b5dcacb Mon Sep 17 00:00:00 2001 From: Ethan Shafran Moltz Date: Thu, 6 Jun 2024 10:40:42 -0400 Subject: [PATCH 1/9] validation for global type --- bun.lockb | Bin 311574 -> 313774 bytes package.json | 1 + src/components/DropZone.tsx | 2 +- src/lib/utils.ts | 20 +++++++++++++++++--- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/bun.lockb b/bun.lockb index 588c8de8c04b7d7e3cb36766c523fc5494cb83f5..05c7159422286da1ecdec21553f9090ed5ff70eb 100755 GIT binary patch delta 25848 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 delta 24264 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 { // Do whatever you want with the file contents after .readAsText() const textStr = reader.result - const array: GlobalDataType[] = parseData(textStr) + const array: GlobalDataType[] | null = parseData(textStr) console.log(array) } reader.readAsText(file) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index aa44d82..b148672 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -2,18 +2,32 @@ import { type ClassValue, clsx } from "clsx" import { twMerge } from "tailwind-merge" import { GlobalDataType } from "./types" import Papa from "papaparse" +import Joi from "joi" export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } +const schema = Joi.array().items( + Joi.object({ + 'Problem Name': Joi.string().required(), + 'Step Name': Joi.string().required(), + 'Outcome': Joi.string().valid('ERROR', 'OK').required(), + }) +); -export function parseData(readerResult: string | ArrayBuffer | null, delimiter: "\t" | "," | "|" = "\t"): GlobalDataType[] { +export function parseData(readerResult: string | ArrayBuffer | null, delimiter: "\t" | "," | "|" = "\t"): GlobalDataType[] | null { const textStr = readerResult const results = Papa.parse(textStr as string, { - header: true, - delimiter: delimiter + header: true, + delimiter: delimiter }) const array: GlobalDataType[] = results.data as GlobalDataType[] + const { error } = schema.validate(array); + if (error){ + console.error(error) + return null; + } + return array } \ No newline at end of file From 7e08acce4b4cadbaa2cebcbdae69ed07f290f117 Mon Sep 17 00:00:00 2001 From: Ethan Shafran Moltz Date: Thu, 6 Jun 2024 10:44:32 -0400 Subject: [PATCH 2/9] correct validation now --- src/lib/utils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index b148672..feffff8 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -11,9 +11,9 @@ export function cn(...inputs: ClassValue[]) { const schema = Joi.array().items( Joi.object({ 'Problem Name': Joi.string().required(), - 'Step Name': Joi.string().required(), - 'Outcome': Joi.string().valid('ERROR', 'OK').required(), - }) + 'Step Name': Joi.string().allow('', null), + 'Outcome': Joi.string().valid('OK', 'BUG', 'INITIAL_HINT', 'HINT_LEVEL_CHANGE', 'ERROR').required(), + }).unknown() ); export function parseData(readerResult: string | ArrayBuffer | null, delimiter: "\t" | "," | "|" = "\t"): GlobalDataType[] | null { From 2b6624db6b98bbea2b63f601b2d93f957110c03a Mon Sep 17 00:00:00 2001 From: Ethan Shafran Moltz Date: Thu, 6 Jun 2024 11:54:08 -0400 Subject: [PATCH 3/9] feat: Add flex layout to DropZone component --- bun.lockb | Bin 313774 -> 313838 bytes package.json | 2 + src/App.tsx | 4 +- src/components/DropZone.tsx | 105 +++++++++++++++++++++++++----- src/components/ui/label.tsx | 24 +++++++ src/components/ui/radio-group.tsx | 42 ++++++++++++ src/lib/types.ts | 2 +- src/lib/utils.ts | 14 ++-- 8 files changed, 169 insertions(+), 24 deletions(-) create mode 100644 src/components/ui/label.tsx create mode 100644 src/components/ui/radio-group.tsx diff --git a/bun.lockb b/bun.lockb index 05c7159422286da1ecdec21553f9090ed5ff70eb..a75f671073c5f3565719cd5508ea4a140cf6fe03 100755 GIT binary patch delta 34774 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 delta 34704 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 SQAsRc;^SBNd5%xnA^!(E -
-
+
+
diff --git a/src/components/DropZone.tsx b/src/components/DropZone.tsx index 62ddfcf..e205926 100644 --- a/src/components/DropZone.tsx +++ b/src/components/DropZone.tsx @@ -1,9 +1,15 @@ -import { useCallback } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { Accept, useDropzone } from 'react-dropzone'; import { GlobalDataType } from '@/lib/types'; import { parseData } from '@/lib/utils'; +import { Label } from "@/components/ui/label" +import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" export default function DropZone() { + const delimiters = ["tsv", "csv", "pipe"] + + const [fileType, setFileType] = useState(delimiters[0]) + const onDrop = useCallback((acceptedFiles: File[]) => { acceptedFiles.forEach((file: File) => { const reader = new FileReader() @@ -13,7 +19,29 @@ export default function DropZone() { reader.onload = () => { // Do whatever you want with the file contents after .readAsText() const textStr = reader.result - const array: GlobalDataType[] | null = parseData(textStr) + // find file type and convert to delimeter + let delimeter: string; + switch (fileType) { + case 'tsv': + delimeter = '\t' + break; + case 'csv': + delimeter = ',' + break; + case 'pipe': + delimeter = '|' + break; + case 'json': + delimeter = '' + break; + default: + delimeter = '\t' + break; + } + + + + const array: GlobalDataType[] | null = parseData(textStr, delimeter) console.log(array) } reader.readAsText(file) @@ -30,22 +58,65 @@ export default function DropZone() { accept: acceptedFileTypes, }); + const fileTypeOptions = [ + { + label: 'Tab Separated', + value: delimiters.find((delimiter) => delimiter === 'tsv') as string + }, + { + label: 'Comma Separated', + value: delimiters.find((delimiter) => delimiter === 'csv') as string + }, + { + label: 'Pipe Separated', + value: delimiters.find((delimiter) => delimiter === 'pipe') as string + }, + // { + // label: 'JSON', + // value: delimiters.find((delimiter) => delimiter === 'json') as string + // } + ] return ( -
- - { - (isDragActive && !isDragReject) ? -

Drop em here

: -

Drag 'n' drop some files here, or click to select files

- } - { - isDragReject && -

File type not accepted, please try again

+ <> +
+
+ File Type +
+ { + setFileType(e) - } -
+ }}> + {fileTypeOptions.map((option, index) => ( +
+ + +
+ ))} + +
+
+ + { + !isDragActive ? +
+

Drag 'n' drop some files here, or click to select files

+
+ : +
+

Drag 'n' drop some files here, or click to select files

+
+ } + { + isDragReject && +

File type not accepted, please try again

+ + } +
+ + + ); } \ No newline at end of file diff --git a/src/components/ui/label.tsx b/src/components/ui/label.tsx new file mode 100644 index 0000000..683faa7 --- /dev/null +++ b/src/components/ui/label.tsx @@ -0,0 +1,24 @@ +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const labelVariants = cva( + "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" +) + +const Label = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, ...props }, ref) => ( + +)) +Label.displayName = LabelPrimitive.Root.displayName + +export { Label } diff --git a/src/components/ui/radio-group.tsx b/src/components/ui/radio-group.tsx new file mode 100644 index 0000000..43b43b4 --- /dev/null +++ b/src/components/ui/radio-group.tsx @@ -0,0 +1,42 @@ +import * as React from "react" +import * as RadioGroupPrimitive from "@radix-ui/react-radio-group" +import { Circle } from "lucide-react" + +import { cn } from "@/lib/utils" + +const RadioGroup = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + return ( + + ) +}) +RadioGroup.displayName = RadioGroupPrimitive.Root.displayName + +const RadioGroupItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + return ( + + + + + + ) +}) +RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName + +export { RadioGroup, RadioGroupItem } diff --git a/src/lib/types.ts b/src/lib/types.ts index 114a05f..a2116c7 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -6,7 +6,7 @@ export type DataSet1 = { "Transaction Id": string; "Anon Student Id": string; "Session Id": "no_session_tracking"; - Time: string; + Time: string; // Assume data is sorted by time "Time Zone": boolean | null; "Duration (sec)": number | null; "Student Response Type": boolean | null; diff --git a/src/lib/utils.ts b/src/lib/utils.ts index feffff8..98f4be0 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -8,7 +8,7 @@ export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } -const schema = Joi.array().items( +const validation = Joi.array().items( Joi.object({ 'Problem Name': Joi.string().required(), 'Step Name': Joi.string().allow('', null), @@ -16,15 +16,21 @@ const schema = Joi.array().items( }).unknown() ); -export function parseData(readerResult: string | ArrayBuffer | null, delimiter: "\t" | "," | "|" = "\t"): GlobalDataType[] | null { +export function parseData(readerResult: string | ArrayBuffer | null, delimiter: string = "\t"): GlobalDataType[] | null { const textStr = readerResult const results = Papa.parse(textStr as string, { header: true, delimiter: delimiter }) + if (results.errors.length > 0) { + console.error("error during parsing: ", results.errors) + return null; + + } + const array: GlobalDataType[] = results.data as GlobalDataType[] - const { error } = schema.validate(array); - if (error){ + const { error } = validation.validate(array); + if (error) { console.error(error) return null; } From 8adba9939591d89f769c18ddbb5ca7e058286a29 Mon Sep 17 00:00:00 2001 From: Ethan Shafran Moltz Date: Thu, 6 Jun 2024 14:38:17 -0400 Subject: [PATCH 4/9] added navbar and better support for data dropping --- bun.lockb | Bin 313838 -> 313894 bytes package.json | 2 + src/App.tsx | 95 ++++++++---------- src/components/DirectedGraph.tsx | 1 - src/components/DropZone.tsx | 17 +++- src/components/NavBar.tsx | 65 ++++++++++++ src/components/ui/alert-dialog.tsx | 139 ++++++++++++++++++++++++++ src/components/ui/navigation-menu.tsx | 128 ++++++++++++++++++++++++ 8 files changed, 389 insertions(+), 58 deletions(-) create mode 100644 src/components/NavBar.tsx create mode 100644 src/components/ui/alert-dialog.tsx create mode 100644 src/components/ui/navigation-menu.tsx diff --git a/bun.lockb b/bun.lockb index a75f671073c5f3565719cd5508ea4a140cf6fe03..88f2bbcabfb270f625a000975a4622b6cce978f3 100755 GIT binary patch delta 34552 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 delta 34985 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 + const [graphData, setGraphData] = useState(null) + const [isLoading, setIsLoading] = useState(false) + const [showDirectedGraph, setShowDirectedGraph] = useState(false) - // const { pathAnalysisData, isPathAnalysisDataLoading } = usePathAnalysisData(sectionId, problemId); - // const { dataShopData, isDataShopDataLoading } = useDataShopData(); - const filePath = "analyzing_different_forms_of_expressions.json" - // const { localSampleData, isLocalSampleDataLoading } = useLocalSampleData(filePath) - const [processedPathAnalysisData, setProcessedPathAnalysisData] = useState(null); - const [processedShopData, setProcessedShopData] = useState(null); + const handleData = (data: GlobalDataType[]) => { + setProcessedData(data) + } - // useEffect( () => { - // if (isDataShopDataLoading) { - // return; - // } - // else{ - // console.log("dataShopData: ", dataShopData); - // } - // }, [isDataShopDataLoading, dataShopData]) + const handleLoading = (loading: boolean) => { + setIsLoading(loading) + } - // useEffect(() => { - // if (isLocalSampleDataLoading) { - // return; - // } - // if (localSampleData) { - // const _processData = async () => { - // const processedData = await processDataShopData(localSampleData as GlobalDataType[]) - // setProcessedShopData(processedData); - // } - // _processData(); - // } - // }, [isLocalSampleDataLoading, localSampleData]) + useEffect(() => { + if (processedData) { + console.log(processedData); + } - // useEffect(() => { - // const _processData = async () => { - // if (pathAnalysisData) { - // setProcessedPathAnalysisData(await processPathAnalysisData(convertDataTypesIncomingData(pathAnalysisData))); - // } - // } - // _processData(); - - // }, [isPathAnalysisDataLoading, pathAnalysisData]) - - // if (isPathAnalysisDataLoading || !processedPathAnalysisData || !processedShopData) { - // return

Loading...
- // } + }, [processedData]) return ( <> -
+
- +
- {/* */} -
+
+ + { + isLoading ? +
+
+

Loading...

+
+
+ : +
+ +
+ } + + { + graphData && ( + + ) + } + +
+
) } diff --git a/src/components/DirectedGraph.tsx b/src/components/DirectedGraph.tsx index 1ecd5ef..6ede644 100644 --- a/src/components/DirectedGraph.tsx +++ b/src/components/DirectedGraph.tsx @@ -17,7 +17,6 @@ interface DirectedGraphProps { } export default function DirectedGraph({ graphData }: DirectedGraphProps) { - console.log("graphData: ", graphData); const initialTooltip: ToolTip = { display: false, text: '', x: 0, y: 0, fx: undefined, fy: undefined }; const [tooltip, setTooltip] = useState(initialTooltip); diff --git a/src/components/DropZone.tsx b/src/components/DropZone.tsx index e205926..092e4b0 100644 --- a/src/components/DropZone.tsx +++ b/src/components/DropZone.tsx @@ -5,12 +5,18 @@ import { parseData } from '@/lib/utils'; import { Label } from "@/components/ui/label" import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" -export default function DropZone() { +interface DropZoneProps { + afterDrop: (data: GlobalDataType[]) => void, + onLoadingChange: (loading: boolean) => void +} + +export default function DropZone({afterDrop, onLoadingChange}: DropZoneProps) { const delimiters = ["tsv", "csv", "pipe"] const [fileType, setFileType] = useState(delimiters[0]) const onDrop = useCallback((acceptedFiles: File[]) => { + onLoadingChange(true); acceptedFiles.forEach((file: File) => { const reader = new FileReader() @@ -38,11 +44,12 @@ export default function DropZone() { delimeter = '\t' break; } - - - const array: GlobalDataType[] | null = parseData(textStr, delimeter) - console.log(array) + if (array) { + afterDrop(array); + } + onLoadingChange(false); + // console.log(array) } reader.readAsText(file) }) diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx new file mode 100644 index 0000000..0cfa07b --- /dev/null +++ b/src/components/NavBar.tsx @@ -0,0 +1,65 @@ +import { + NavigationMenu, + NavigationMenuContent, + NavigationMenuIndicator, + NavigationMenuItem, + // NavigationMenuLink, + NavigationMenuList, + NavigationMenuTrigger, + // NavigationMenuViewport, +} from "@/components/ui/navigation-menu" +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from "@/components/ui/alert-dialog" + + +export function NavBar() { + return ( +
+ + + + File + + + +
+ Upload Data +
+
+ + + + Upload Data + + + + {/* TODO add dropzone here as modal and handle data in global context */} + + + + Cancel + Continue + + +
+ +
+
+ +
+
+ +
+ ) +} \ No newline at end of file diff --git a/src/components/ui/alert-dialog.tsx b/src/components/ui/alert-dialog.tsx new file mode 100644 index 0000000..8722561 --- /dev/null +++ b/src/components/ui/alert-dialog.tsx @@ -0,0 +1,139 @@ +import * as React from "react" +import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" + +import { cn } from "@/lib/utils" +import { buttonVariants } from "@/components/ui/button" + +const AlertDialog = AlertDialogPrimitive.Root + +const AlertDialogTrigger = AlertDialogPrimitive.Trigger + +const AlertDialogPortal = AlertDialogPrimitive.Portal + +const AlertDialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName + +const AlertDialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + +)) +AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName + +const AlertDialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +AlertDialogHeader.displayName = "AlertDialogHeader" + +const AlertDialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +AlertDialogFooter.displayName = "AlertDialogFooter" + +const AlertDialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName + +const AlertDialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogDescription.displayName = + AlertDialogPrimitive.Description.displayName + +const AlertDialogAction = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName + +const AlertDialogCancel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +} diff --git a/src/components/ui/navigation-menu.tsx b/src/components/ui/navigation-menu.tsx new file mode 100644 index 0000000..1419f56 --- /dev/null +++ b/src/components/ui/navigation-menu.tsx @@ -0,0 +1,128 @@ +import * as React from "react" +import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu" +import { cva } from "class-variance-authority" +import { ChevronDown } from "lucide-react" + +import { cn } from "@/lib/utils" + +const NavigationMenu = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + {children} + + +)) +NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName + +const NavigationMenuList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName + +const NavigationMenuItem = NavigationMenuPrimitive.Item + +const navigationMenuTriggerStyle = cva( + "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50" +) + +const NavigationMenuTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + {children}{" "} + +)) +NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName + +const NavigationMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName + +const NavigationMenuLink = NavigationMenuPrimitive.Link + +const NavigationMenuViewport = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( +
+ +
+)) +NavigationMenuViewport.displayName = + NavigationMenuPrimitive.Viewport.displayName + +const NavigationMenuIndicator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +
+ +)) +NavigationMenuIndicator.displayName = + NavigationMenuPrimitive.Indicator.displayName + +export { + navigationMenuTriggerStyle, + NavigationMenu, + NavigationMenuList, + NavigationMenuItem, + NavigationMenuContent, + NavigationMenuTrigger, + NavigationMenuLink, + NavigationMenuIndicator, + NavigationMenuViewport, +} From 6d44efa5c802e983c48a8c138544ed77620ade78 Mon Sep 17 00:00:00 2001 From: Ethan Shafran Moltz Date: Thu, 6 Jun 2024 15:32:00 -0400 Subject: [PATCH 5/9] Context template for app --- src/Context.tsx | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/Context.tsx diff --git a/src/Context.tsx b/src/Context.tsx new file mode 100644 index 0000000..76a00d7 --- /dev/null +++ b/src/Context.tsx @@ -0,0 +1,21 @@ +import { createContext } from 'react'; +interface ContextInterface { + +} +export const Context = createContext({} as ContextInterface); + +const initialState = { + +} + +interface ProviderProps { + children: React.ReactNode; +} +export const Provider = ({ children }: ProviderProps) => { + return ( + + {children} + +} \ No newline at end of file From 249ed9636f37097c2fefe6df1c65677ea207b386 Mon Sep 17 00:00:00 2001 From: Ethan Shafran Moltz Date: Thu, 6 Jun 2024 15:33:28 -0400 Subject: [PATCH 6/9] quick bug fix --- src/Context.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Context.tsx b/src/Context.tsx index 76a00d7..80c5db4 100644 --- a/src/Context.tsx +++ b/src/Context.tsx @@ -18,4 +18,5 @@ export const Provider = ({ children }: ProviderProps) => { > {children} + ) } \ No newline at end of file From 0fe647cadc7606678e0d907b2befe2c5cc2cb1e2 Mon Sep 17 00:00:00 2001 From: Ethan Shafran Moltz Date: Thu, 6 Jun 2024 15:35:05 -0400 Subject: [PATCH 7/9] again some changes to template --- src/Context.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Context.tsx b/src/Context.tsx index 80c5db4..82ef1d8 100644 --- a/src/Context.tsx +++ b/src/Context.tsx @@ -1,4 +1,4 @@ -import { createContext } from 'react'; +import { createContext, useState } from 'react'; interface ContextInterface { } @@ -14,7 +14,7 @@ interface ProviderProps { export const Provider = ({ children }: ProviderProps) => { return ( {children} From e1e1ad92f95d0879b9d4b73b088f2c75f940a8af Mon Sep 17 00:00:00 2001 From: Ethan Shafran Moltz Date: Fri, 7 Jun 2024 10:04:36 -0400 Subject: [PATCH 8/9] added context to state --- src/App.tsx | 1 - src/Context.tsx | 26 +++++++++++++++++++++++--- src/main.tsx | 7 ++++++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 9d1ae29..92dfd50 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -10,7 +10,6 @@ function App() { const [processedData, setProcessedData] = useState(null) const [graphData, setGraphData] = useState(null) const [isLoading, setIsLoading] = useState(false) - const [showDirectedGraph, setShowDirectedGraph] = useState(false) const handleData = (data: GlobalDataType[]) => { setProcessedData(data) diff --git a/src/Context.tsx b/src/Context.tsx index 82ef1d8..d3274ea 100644 --- a/src/Context.tsx +++ b/src/Context.tsx @@ -1,20 +1,40 @@ import { createContext, useState } from 'react'; +import { GlobalDataType, GraphData } from './lib/types'; interface ContextInterface { + data: GlobalDataType[] | null; + graphData: GraphData | null; + loading: boolean; + setLoading: (loading: boolean) => void; + setData: (data: GlobalDataType[] | null) => void; + setGraphData: (graphData: GraphData | null) => void; } export const Context = createContext({} as ContextInterface); - const initialState = { - + data: null, + graphData: null, + loading: false } interface ProviderProps { children: React.ReactNode; } export const Provider = ({ children }: ProviderProps) => { + const [data, setData] = useState(initialState.data) + const [graphData, setGraphData] = useState(initialState.graphData) + const [loading, setLoading] = useState(initialState.loading) + + return ( {children} diff --git a/src/main.tsx b/src/main.tsx index 2b1a1aa..cb22913 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -7,13 +7,18 @@ import { QueryClientProvider, } from '@tanstack/react-query' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' +import { Provider } from './Context.tsx' const queryClient = new QueryClient() ReactDOM.createRoot(document.getElementById('root')!).render( - + + + + + , From 7d9944a49cd223dc15ea2938b6ef1d5367330f3e Mon Sep 17 00:00:00 2001 From: Ethan Shafran Moltz Date: Fri, 7 Jun 2024 10:33:38 -0400 Subject: [PATCH 9/9] feat: Add reset functionality to App component --- src/App.tsx | 39 ++++++++++++++++++++++----------------- src/Context.tsx | 10 +++++++++- src/components/NavBar.tsx | 19 ++++++++++++++----- 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 92dfd50..67fd05e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,43 +1,48 @@ import './App.css'; -import { useEffect, useState } from 'react'; +import { useContext, useEffect, useState } from 'react'; import { GlobalDataType, GraphData } from './lib/types'; import DirectedGraph from './components/DirectedGraph'; import DropZone from './components/DropZone'; -import { NavBar } from './components/NavBar'; +// import { NavBar } from './components/NavBar'; +import { Button } from './components/ui/button'; +import { Context } from './Context'; function App() { - // TODO move to global context - const [processedData, setProcessedData] = useState(null) - const [graphData, setGraphData] = useState(null) - const [isLoading, setIsLoading] = useState(false) + const { resetData, setGraphData, setLoading, data, setData, graphData, loading } = useContext(Context) const handleData = (data: GlobalDataType[]) => { - setProcessedData(data) + setData(data) } const handleLoading = (loading: boolean) => { - setIsLoading(loading) + setLoading(loading) } useEffect(() => { - if (processedData) { - console.log(processedData); + if (data) { + console.log(data); } - - - }, [processedData]) + }, [data]) return ( <>
-
- -
+ {/* */} +
{ - isLoading ? + loading ?

Loading...

diff --git a/src/Context.tsx b/src/Context.tsx index d3274ea..3e03b0f 100644 --- a/src/Context.tsx +++ b/src/Context.tsx @@ -7,6 +7,7 @@ interface ContextInterface { setLoading: (loading: boolean) => void; setData: (data: GlobalDataType[] | null) => void; setGraphData: (graphData: GraphData | null) => void; + resetData: () => void; } export const Context = createContext({} as ContextInterface); @@ -24,6 +25,12 @@ export const Provider = ({ children }: ProviderProps) => { const [graphData, setGraphData] = useState(initialState.graphData) const [loading, setLoading] = useState(initialState.loading) + const resetData = () => { + setData(null) + setGraphData(null) + console.log("Data reset"); + + } return ( { loading, setLoading, setData, - setGraphData + setGraphData, + resetData }} > {children} diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx index 0cfa07b..cdfb9e4 100644 --- a/src/components/NavBar.tsx +++ b/src/components/NavBar.tsx @@ -19,22 +19,26 @@ import { AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog" - +import { useContext } from "react" +import { Context } from "@/Context" +import DropZone from "./DropZone" +import { GlobalDataType } from "@/lib/types" export function NavBar() { + return (
- File + Upload
- Upload Data + Upload and Process Data
@@ -44,7 +48,12 @@ export function NavBar() { - {/* TODO add dropzone here as modal and handle data in global context */} + {/* { }} + onLoadingChange={(loading) => { + setLoading(loading) + }} + /> */} @@ -53,7 +62,7 @@ export function NavBar() {
- +