Cyber V0.01 Revision on the GPT Store
GPT Description
GPT Prompt Starters
- Act as Ty the Programmer and generate a game
- Act as ty the programmer and format thtis with react grid layout /** * v0 by Vercel. * @see https://v0.dev/t/B45X5uIWMxE * Documentation: https://v0.dev/docs#integrating-generated-code-into-your-nextjs-app */ import { Button } from "@/components/ui/button" import { ScatterPlotRawSerie } from "@nivo/scatterplot" import { exportToExcel } from "../utils/excel/exportToExcel" import { preprocessScatterDataForExport } from "../utils/excel/exportToExcel" import { useEffect, useState } from "react" import { ExtendedScatterPlotDatum, } from "@/data/mockData/scatterPlot/socials" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import StackedBarGraph from "../graphs/stackedBargraph" import { barDataOptions } from "@/data/mockData/barGraph/socials" import PlatformList from "../utils/analytics/platformList" import TrafficList from "../utils/analytics/trafficTrends" import TargetAudienceList from "../utils/analytics/targetAudienceList" import TrendCard from "../utils/analytics/google/trends" import SimilarProfilesList from "../utils/analytics/similarAccounts" import TrendingSoundsList from "../utils/analytics/trendingSounds" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; import HorizontalAccordion from "../utils/accordianDynamic" import { mockUserSettings } from "@/data/mockData/settings/userSettings" import { SettingsModal } from "../userSettings" import UploadManager from "../utils/uploadManager" interface DynamicDataChatProps { title: string; subtitle: string; data: Record<string, ScatterPlotRawSerie<ExtendedScatterPlotDatum>[]>; // Correctly typed for scatter plot data } export const DynamicDataChat: React.FC<DynamicDataChatProps> = ({ title, data, }) => { const [refreshed, setRefreshed] = useState(false); const [selectedSite, setSelectedSite] = useState<string>("Facebook"); const handleSelectChange = (site: string) => { setSelectedSite(site); }; useEffect(() => { setRefreshed(false); }, [refreshed]); return ( <div className="flex w-full max-w-full flex-col md:flex-row"> <div className="flex-1 rounded-l-lg bg-white p-6 shadow-lg dark:bg-gray-950"> <div className="mb-6 flex items-center justify-between"> <h2 className="text-2xl font-semibold">{title}</h2> <div className="flex items-center space-x-4"> <Button onClick={() => setRefreshed(!refreshed)} size="icon" variant="outline"> <RefreshCwIcon className="h-5 w-5" /> <span className="sr-only">Refresh</span> </Button> <Button size="icon" variant="outline" onClick={() => { const processedData = preprocessScatterDataForExport(data); exportToExcel(processedData, "InstagramEngagement"); }} > <DownloadIcon className="h-5 w-5" /> <span className="sr-only">Download</span> </Button> </div> </div> <div> <DropdownMenu> <DropdownMenuTrigger className="rounded bg-blue-500 px-4 py-2 text-white"> Select Social Media Site </DropdownMenuTrigger> <DropdownMenuContent> <DropdownMenuLabel>Social Media Sites</DropdownMenuLabel> <DropdownMenuSeparator /> {Object.keys(barDataOptions).map((site) => ( <DropdownMenuItem key={site} onSelect={() => handleSelectChange(site)}> {site} </DropdownMenuItem> ))} </DropdownMenuContent> </DropdownMenu> </div> <div className="absolute top-0 mt-16 text-lg font-semibold"> Selected Site: {selectedSite} </div> <div className=" rounded-lg border border-gray-200 dark:border-gray-800"> <StackedBarGraph passedData={barDataOptions} selectedSites={["Facebook", "Instagram"]} /> </div> <div className="flex flex-wrap items-start justify-center bg-gray-900 p-4 text-white"> <div className="w-full p-2 md:w-1/3"> <PlatformList /> </div> <div className="w-full p-2 md:w-1/3"> <TrafficList /> </div> <div className="w-full p-2 md:w-1/3"> <TargetAudienceList /> </div> <div className="w-full p-2 md:w-1/3"> <TrendCard /> </div> <div className="w-full p-2 md:w-1/3"> <SimilarProfilesList /> </div> <div className="w-full p-2 md:w-1/3"> <TrendingSoundsList /> </div> </div> </div> <div className="flex w-full flex-col rounded-r-lg bg-white px-4 py-4 shadow-lg dark:bg-gray-950 md:w-1/3"> <div className="mb-6 flex items-center justify-between flex-row-reverse"> {/* Change flex direction */} <div className="flex"> {/* Keep flex direction as default (row) */} <TooltipProvider> <UploadManager/> <SettingsModal button={ <Tooltip> <TooltipTrigger> <Button size="icon" className="mx-2" variant="outline"> <SettingsIcon className="h-5 w-5" /> <span className="sr-only">Settings</span> </Button> </TooltipTrigger> <TooltipContent> <p>Settings</p> </TooltipContent> </Tooltip> } /> </TooltipProvider> </div> </div> <div className=""> <HorizontalAccordion tabs={mockUserSettings.preferences.tabs} /> </div> </div> </div> ); }; function DownloadIcon(props: any) { return ( <svg {...props} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" > <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /> <polyline points="7 10 12 15 17 10" /> <line x1="12" x2="12" y1="15" y2="3" /> </svg> ) } function RefreshCwIcon(props: any) { return ( <svg {...props} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" > <path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" /> <path d="M21 3v5h-5" /> <path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" /> <path d="M8 16H3v5" /> </svg> ) } function SettingsIcon(props: any) { return ( <svg {...props} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" > <path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" /> <circle cx="12" cy="12" r="3" /> </svg> ) } ensuring the user can quickly edit the layout/ configuration of components :: https://github.com/react-grid-layout/react-grid-layout React-Grid-Layout is a grid layout system much like Packery or Gridster, for React. Unlike those systems, it is responsive and supports breakpoints. Breakpoint layouts can be provided by the user or autogenerated. RGL is React-only and does not require jQuery. 100% React - no jQuery Compatible with server-rendered apps Draggable widgets Resizable widgets Static widgets Configurable packing: horizontal, vertical, or off Bounds checking for dragging and resizing Widgets may be added or removed without rebuilding grid Layout can be serialized and restored Responsive breakpoints Separate layouts per responsive breakpoint Grid Items placed using CSS Transforms Performance with CSS Transforms: on / off, note paint (green) as % of time Compatibility with <React.StrictMode>[{Usage Use ReactGridLayout like any other component. The following example below will produce a grid with three items where: users will not be able to drag or resize item a item b will be restricted to a minimum width of 2 grid blocks and a maximum width of 4 grid blocks users will be able to freely drag and resize item c import GridLayout from "react-grid-layout"; class MyFirstGrid extends React.Component { render() { // layout is an array of objects, see the demo for more complete usage const layout = [ { i: "a", x: 0, y: 0, w: 1, h: 2, static: true }, { i: "b", x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4 }, { i: "c", x: 4, y: 0, w: 1, h: 2 } ]; return ( <GridLayout className="layout" layout={layout} cols={12} rowHeight={30} width={1200} > <div key="a">a</div> <div key="b">b</div> <div key="c">c</div> </GridLayout> ); } } You may also choose to set layout properties directly on the children: import GridLayout from "react-grid-layout"; class MyFirstGrid extends React.Component { render() { return ( <GridLayout className="layout" cols={12} rowHeight={30} width={1200}> <div key="a" data-grid={{ x: 0, y: 0, w: 1, h: 2, static: true }}> a </div> <div key="b" data-grid={{ x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4 }}> b </div> <div key="c" data-grid={{ x: 4, y: 0, w: 1, h: 2 }}> c </div> </GridLayout> ); } } Usage without Browserify/Webpack A module usable in a <script> tag is included here. It uses a UMD shim and excludes React, so it must be otherwise available in your application, either via RequireJS or on window.React. Responsive Usage To make RGL responsive, use the <ResponsiveReactGridLayout> element: import { Responsive as ResponsiveGridLayout } from "react-grid-layout"; class MyResponsiveGrid extends React.Component { render() { // {lg: layout1, md: layout2, ...} const layouts = getLayoutsFromSomewhere(); return ( <ResponsiveGridLayout className="layout" layouts={layouts} breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }} cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }} > <div key="1">1</div> <div key="2">2</div> <div key="3">3</div> </ResponsiveGridLayout> ); } } When in responsive mode, you should supply at least one breakpoint via the layouts property. When using layouts, it is best to supply as many breakpoints as possible, especially the largest one. If the largest is provided, RGL will attempt to interpolate the rest. You will also need to provide a width, when using <ResponsiveReactGridLayout> it is suggested you use the HOC WidthProvider as per the instructions below. It is possible to supply default mappings via the data-grid property on individual items, so that they would be taken into account within layout interpolation. Providing Grid Width Both <ResponsiveReactGridLayout> and <ReactGridLayout> take width to calculate positions on drag events. In simple cases a HOC WidthProvider can be used to automatically determine width upon initialization and window resize events. import { Responsive, WidthProvider } from "react-grid-layout"; const ResponsiveGridLayout = WidthProvider(Responsive); class MyResponsiveGrid extends React.Component { render() { // {lg: layout1, md: layout2, ...} var layouts = getLayoutsFromSomewhere(); return ( <ResponsiveGridLayout className="layout" layouts={layouts} breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }} cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }} > <div key="1">1</div> <div key="2">2</div> <div key="3">3</div> </ResponsiveGridLayout> ); } } This allows you to easily replace WidthProvider with your own Provider HOC if you need more sophisticated logic. WidthProvider accepts a single prop, measureBeforeMount. If true, WidthProvider will measure the container's width before mounting children. Use this if you'd like to completely eliminate any resizing animation on application/component mount. Have a more complicated layout? WidthProvider is very simple and only listens to window 'resize' events. If you need more power and flexibility, try the SizeMe React HOC as an alternative to WidthProvider. Grid Layout Props RGL supports the following properties (see the source for the final word on this): // // Basic props // // This allows setting the initial width on the server side. // This is required unless using the HOC <WidthProvider> or similar width: number, // If true, the container height swells and contracts to fit contents autoSize: ?boolean = true, // Number of columns in this layout. cols: ?number = 12, // A CSS selector for tags that will not be draggable. // For example: draggableCancel:'.MyNonDraggableAreaClassName' // If you forget the leading . it will not work. // .react-resizable-handle" is always prepended to this value. draggableCancel: ?string = '', // A CSS selector for tags that will act as the draggable handle. // For example: draggableHandle:'.MyDragHandleClassName' // If you forget the leading . it will not work. draggableHandle: ?string = '', // Compaction type. compactType: ?('vertical' | 'horizontal' | null) = 'vertical'; // Layout is an array of object with the format: // {x: number, y: number, w: number, h: number} // The index into the layout must match the key used on each item component. // If you choose to use custom keys, you can specify that key in the layout // array objects like so: // {i: string, x: number, y: number, w: number, h: number} layout: ?array = null, // If not provided, use data-grid props on children // Margin between items [x, y] in px. margin: ?[number, number] = [10, 10], // Padding inside the container [x, y] in px containerPadding: ?[number, number] = margin, // Rows have a static height, but you can change this based on breakpoints // if you like. rowHeight: ?number = 150, // Configuration of a dropping element. Dropping element is a "virtual" element // which appears when you drag over some element from outside. // It can be changed by passing specific parameters: // i - id of an element // w - width of an element // h - height of an element droppingItem?: { i: string, w: number, h: number } // // Flags // isDraggable: ?boolean = true, isResizable: ?boolean = true, isBounded: ?boolean = false, // Uses CSS3 translate() instead of position top/left. // This makes about 6x faster paint performance useCSSTransforms: ?boolean = true, // If parent DOM node of ResponsiveReactGridLayout or ReactGridLayout has "transform: scale(n)" css property, // we should set scale coefficient to avoid render artefacts while dragging. transformScale: ?number = 1, // If true, grid can be placed one over the other. // If set, implies `preventCollision`. allowOverlap: ?boolean = false, // If true, grid items won't change position when being // dragged over. If `allowOverlap` is still false, // this simply won't allow one to drop on an existing object. preventCollision: ?boolean = false, // If true, droppable elements (with `draggable={true}` attribute) // can be dropped on the grid. It triggers "onDrop" callback // with position and event object as parameters. // It can be useful for dropping an element in a specific position // // NOTE: In case of using Firefox you should add // `onDragStart={e => e.dataTransfer.setData('text/plain', '')}` attribute // along with `draggable={true}` otherwise this feature will work incorrect. // onDragStart attribute is required for Firefox for a dragging initialization // @see https://bugzilla.mozilla.org/show_bug.cgi?id=568313 isDroppable: ?boolean = false, // Defines which resize handles should be rendered. // Allows for any combination of: // 's' - South handle (bottom-center) // 'w' - West handle (left-center) // 'e' - East handle (right-center) // 'n' - North handle (top-center) // 'sw' - Southwest handle (bottom-left) // 'nw' - Northwest handle (top-left) // 'se' - Southeast handle (bottom-right) // 'ne' - Northeast handle (top-right) // // Note that changing this property dynamically does not work due to a restriction in react-resizable. resizeHandles: ?Array<'s' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne'> = ['se'], // Custom component for resize handles // See `handle` as used in https://github.com/react-grid-layout/react-resizable#resize-handle // Your component should have the class `.react-resizable-handle`, or you should add your custom // class to the `draggableCancel` prop. resizeHandle?: ReactElement<any> | ((resizeHandleAxis: ResizeHandleAxis, ref: ReactRef<HTMLElement>) => ReactElement<any>), // // Callbacks // // Callback so you can save the layout. // Calls back with (currentLayout) after every drag or resize stop. onLayoutChange: (layout: Layout) => void, // // All callbacks below have signature (layout, oldItem, newItem, placeholder, e, element). // 'start' and 'stop' callbacks pass `undefined` for 'placeholder'. // type ItemCallback = (layout: Layout, oldItem: LayoutItem, newItem: LayoutItem, placeholder: LayoutItem, e: MouseEvent, element: HTMLElement) => void, // Calls when drag starts. onDragStart: ItemCallback, // Calls on each drag movement. onDrag: ItemCallback, // Calls when drag is complete. onDragStop: ItemCallback, // Calls when resize starts. onResizeStart: ItemCallback, // Calls when resize movement happens. onResize: ItemCallback, // Calls when resize is complete. onResizeStop: ItemCallback, // // Dropover functionality // // Calls when an element has been dropped into the grid from outside. onDrop: (layout: Layout, item: ?LayoutItem, e: Event) => void, // Calls when an element is being dragged over the grid from outside as above. // This callback should return an object to dynamically change the droppingItem size // Return false to short-circuit the dragover onDropDragOver: (e: DragOverEvent) => ?({|w?: number, h?: number|} | false), // Ref for getting a reference for the grid's wrapping div. // You can use this instead of a regular ref and the deprecated `ReactDOM.findDOMNode()`` function. // Note that this type is React.Ref<HTMLDivElement> in TypeScript, Flow has a bug here // https://github.com/facebook/flow/issues/8671#issuecomment-862634865 innerRef: {current: null | HTMLDivElement}, Responsive Grid Layout Props The responsive grid layout can be used instead. It supports all of the props above, excepting layout. The new properties and changes are: // {name: pxVal}, e.g. {lg: 1200, md: 996, sm: 768, xs: 480} // Breakpoint names are arbitrary but must match in the cols and layouts objects. breakpoints: ?Object = {lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0}, // # of cols. This is a breakpoint -> cols map, e.g. {lg: 12, md: 10, ...} cols: ?Object = {lg: 12, md: 10, sm: 6, xs: 4, xxs: 2}, // margin (in pixels). Can be specified either as horizontal and vertical margin, e.g. `[10, 10]` or as a breakpoint -> margin map, e.g. `{lg: [10, 10], md: [10, 10], ...}. margin: [number, number] | {[breakpoint: $Keys<breakpoints>]: [number, number]}, // containerPadding (in pixels). Can be specified either as horizontal and vertical padding, e.g. `[10, 10]` or as a breakpoint -> containerPadding map, e.g. `{lg: [10, 10], md: [10, 10], ...}. containerPadding: [number, number] | {[breakpoint: $Keys<breakpoints>]: [number, number]}, // layouts is an object mapping breakpoints to layouts. // e.g. {lg: Layout, md: Layout, ...} layouts: {[key: $Keys<breakpoints>]: Layout}, // // Callbacks // // Calls back with breakpoint and new # cols onBreakpointChange: (newBreakpoint: string, newCols: number) => void, // Callback so you can save the layout. // AllLayouts are keyed by breakpoint. onLayoutChange: (currentLayout: Layout, allLayouts: {[key: $Keys<breakpoints>]: Layout}) => void, // Callback when the width changes, so you can modify the layout as needed. onWidthChange: (containerWidth: number, margin: [number, number], cols: number, containerPadding: [number, number]) => void; Grid Item Props RGL supports the following properties on grid items or layout items. When initializing a grid, build a layout array (as in the first example above), or attach this object as the data-grid property to each of your child elements (as in the second example). If data-grid is provided on an item, it will take precedence over an item in the layout with the same key (i). Note that if a grid item is provided but incomplete (missing one of x, y, w, or h), an error will be thrown so you can correct your layout. If no properties are provided for a grid item, one will be generated with a width and height of 1. You can set minimums and maximums for each dimension. This is for resizing; it of course has no effect if resizing is disabled. Errors will be thrown if your mins and maxes overlap incorrectly, or your initial dimensions are out of range. Any <GridItem> properties defined directly will take precedence over globally-set options. For example, if the layout has the property isDraggable: false, but the grid item has the prop isDraggable: true, the item will be draggable, even if the item is marked static: true. { // A string corresponding to the component key i: string, // These are all in grid units, not pixels x: number, y: number, w: number, h: number, minW: ?number = 0, maxW: ?number = Infinity, minH: ?number = 0, maxH: ?number = Infinity, // If true, equal to `isDraggable: false, isResizable: false`. static: ?boolean = false, // If false, will not be draggable. Overrides `static`. isDraggable: ?boolean = true, // If false, will not be resizable. Overrides `static`. isResizable: ?boolean = true, // By default, a handle is only shown on the bottom-right (southeast) corner. // As of RGL >= 1.4.0, resizing on any corner works just fine! resizeHandles?: ?Array<'s' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne'> = ['se'] // If true and draggable, item will be moved only within grid. isBounded: ?boolean = false } Grid Item Heights and Widths Grid item widths are based on container and number of columns. The size of a grid unit's height is based on rowHeight. Note that an item that has h=2 is not exactly twice as tall as one with h=1 unless you have no margin! In order for the grid to not be ragged, when an item spans grid units, it must also span margins. So you must add the height or width or the margin you are spanning for each unit. So actual pixel height is (rowHeight * h) + (marginH * (h - 1). For example, with rowHeight=30, margin=[10,10] and a unit with height 4, the calculation is (30 * 4) + (10 * 3) margin If this is a problem for you, set margin=[0,0] and handle visual spacing between your elements inside the elements' content. Performance <ReactGridLayout> has an optimized shouldComponentUpdate implementation, but it relies on the user memoizing the children array: // lib/ReactGridLayout.jsx // ... shouldComponentUpdate(nextProps: Props, nextState: State) { return ( // NOTE: this is almost always unequal. Therefore the only way to get better performance // from SCU is if the user intentionally memoizes children. If they do, and they can // handle changes properly, performance will increase. this.props.children !== nextProps.children || !fastRGLPropsEqual(this.props, nextProps, isEqual) || !isEqual(this.state.activeDrag, nextState.activeDrag) ); } // ... If you memoize your children, you can take advantage of this, and reap faster rerenders. For example: function MyGrid(props) { const children = React.useMemo(() => { return new Array(props.count).fill(undefined).map((val, idx) => { return <div key={idx} data-grid={{ x: idx, y: 1, w: 1, h: 1 }} />; }); }, [props.count]); return <ReactGridLayout cols={12}>{children}</ReactGridLayout>; } Because the children prop doesn't change between rerenders, updates to <MyGrid> won't result in new renders, improving performance. React Hooks Performance Using hooks to save your layout state on change will cause the layouts to re-render as the ResponsiveGridLayout will change it's value on every render. To avoid this you should wrap your WidthProvider in a useMemo: const ResponsiveReactGridLayout = useMemo(() => WidthProvider(Responsive), []); Custom Child Components and Draggable Handles If you use React Components as grid children, they need to do a few things: Forward refs to an underlying DOM node, and Forward style,className, onMouseDown, onMouseUp and onTouchEnd to that same DOM node. For example: const CustomGridItemComponent = React.forwardRef(({style, className, onMouseDown, onMouseUp, onTouchEnd, children, ...props}, ref) => { return ( <div style={{ /* styles */, ...style}} className={className} ref={ref} onMouseDown={onMouseDown} onMouseUp={onMouseUp} onTouchEnd={onTouchEnd}> {/* Some other content */} {children} {/* Make sure to include children to add resizable handle */} </div> ); }) The same is true of custom elements as draggable handles using the draggableHandle prop. This is so that the underlying react-draggable library can get a reference to the DOM node underneath, manipulate positioning via style, and set classes.}]
- Act as ty the programmer and edit this so it closes the modal when a report is clicked, --onlyoutputchanges true ! import React, { useState, ReactNode } from 'react'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog'; import { ScatterPlotData } from '@/data/mockData/scatterPlot/socials'; import ChatInterface from './excel/chatInterface'; import { WholeWord } from 'lucide-react'; import HtmlThreeDeeGraphDisplay from '../graphs/3d/htmlStringThreeDeeDisplay'; import { BarChartDataOptions, BarChartDataPoint, StackedBarChartDataOptions } from '@/data/mockData/barGraph/socials'; import { PieChartDataOptions } from '../graphs/circleGraph'; import { PieChartDatum } from '../reusables/AI/graphConverter'; import mockReports from '@/data/mockData/reports'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" interface HtmlOrJsonUploaderProps { title?: string; buttonElement: ReactNode; } export interface ChartTypes { BarChart?: BarChartDataOptions; PieChart?: PieChartDataOptions; ScatterPlot?: ScatterPlotData; StackedBarChart?: StackedBarChartDataOptions; } export interface UserReportsType { html?: { url?: string; path?: string; }; data: { graph?: any; charts: ChartTypes; svg?: string }; title: string; preview: string; context: string; timestamp: string; notes: string[]; } export const HtmlOrJsonUploader: React.FC<HtmlOrJsonUploaderProps> = ({ title = 'Upload HTML or JSON File', buttonElement }) => { const [jsonFileName, setJsonFileName] = useState<string | null>(null); const [htmlFileName, setHtmlFileName] = useState<string | null>(null); const [jsonData, setJsonData] = useState<BarChartDataOptions | PieChartDataOptions | StackedBarChartDataOptions | ScatterPlotData>({}); const [isLoading, setIsLoading] = useState(false); const [newFileName, setNewFileName] = useState<string>(''); const [file, setFile] = useState<File | null>(null); const [isModalOpen, setIsModalOpen] = useState(false); const [isConverted, setIsConverted] = useState(false); const [htmlContent, setHtmlContent] = useState<string | null>(null); const [fileNameError, setFileNameError] = useState<string | null>(null); const [success, setSuccess] = useState<string | null>(null); const [error, setError] = useState<string | null>(null); const [isValidFile, setIsValidFile] = useState(false); const [selectedReport, setSelectedReport] = useState<string | null>(null); const [reports, setReports] = useState(mockReports) const extractKeyValuePairs = (data: BarChartDataOptions | PieChartDataOptions | StackedBarChartDataOptions | ScatterPlotData): { [key: string]: any } => { if ('title' in data && 'subtitle' in data && 'data' in data) { // ScatterPlotData return data.data[0] ?? {}; } else { // BarChartDataOptions or PieChartDataOptions const firstKey = Object.keys(data)[0]; return data[firstKey] ? data[firstKey][0] : {}; } }; const handleFileNameChange = (event: React.ChangeEvent<HTMLInputElement>) => { const value = event.target.value; const regex = /^[a-zA-Z0-9-_]+$/; if (regex.test(value) || value === '') { setNewFileName(value); setFileNameError(null); } else { setFileNameError('Filename can only contain alphanumeric characters, hyphens, and underscores.'); } }; const isBarChartDataOptions = (data: any): data is BarChartDataOptions => { return Object.values(data).every((points) => (points as BarChartDataPoint[]).every((point) => typeof point.name === 'string' && typeof point.count === 'number') ); }; const isPieChartDataOptions = (data: any): data is PieChartDataOptions => { return Object.values(data).every((datums) => (datums as PieChartDatum[]).every((datum) => typeof datum.id === 'string' && typeof datum.value === 'number') ); }; const isScatterPlotData = (data: any): data is ScatterPlotData => { return ( typeof data.title === 'string' && typeof data.subtitle === 'string' && Array.isArray(data.data) && data.data.every((series: { data: any; }) => Array.isArray(series.data)) ); }; const parseJsonFile = (file: File) => { const reader = new FileReader(); reader.onload = (e) => { const content = e.target?.result as string | null; if (content) { try { const json = JSON.parse(content); if (isBarChartDataOptions(json) || isPieChartDataOptions(json) || isScatterPlotData(json)) { setIsValidFile(true); setJsonData(json); setSuccess('Processed JSON Successfully'); setIsConverted(true); } else { setError('Invalid JSON format. Please upload a valid JSON file.'); setIsValidFile(false); } } catch (err) { setError('Invalid JSON format. Please upload a valid JSON file.'); setIsValidFile(false); } } else { setError('Invalid JSON format. Please upload a valid JSON file.'); setIsValidFile(false); } }; reader.onerror = () => { setError('Failed to read the file. Please try again.'); setIsValidFile(false); }; reader.readAsText(file); }; const parseHtmlFile = (file: File) => { const reader = new FileReader(); reader.onload = (e) => { const content = e.target?.result as string | null; if (content && content.includes('<html')) { setIsValidFile(true); setSuccess('Processed HTML Successfully'); setHtmlContent(content); setIsConverted(true); } else { setError('Invalid HTML file. Please upload a valid HTML file.'); setIsValidFile(false); } }; reader.onerror = () => { setError('Failed to read the file. Please try again.'); setIsValidFile(false); }; reader.readAsText(file); }; const handleJsonFileChange = (event: React.ChangeEvent<HTMLInputElement>) => { const selectedFile = event.target.files?.[0]; if (selectedFile) { setJsonFileName(selectedFile.name); setFile(selectedFile); setIsConverted(false); validateJsonFile(selectedFile) setError(null); // Reset error state parseJsonFile(selectedFile); } }; const handleHtmlFileChange = (event: React.ChangeEvent<HTMLInputElement>) => { const selectedFile = event.target.files?.[0]; if (selectedFile) { setHtmlFileName(selectedFile.name); setFile(selectedFile); setIsConverted(false); validateHtmlFile(selectedFile) setError(null); // Reset error state parseHtmlFile(selectedFile); } }; const validateJsonFile = (file: File) => { const reader = new FileReader(); reader.onload = (e) => { const content = e.target?.result; if (typeof content === 'string') { try { const json = JSON.parse(content); if (isBarChartDataOptions(json) || isPieChartDataOptions(json) || isScatterPlotData(json)) { setIsValidFile(true); setSuccess('Processed JSON Successfully'); setIsConverted(true); } else { setError('Invalid JSON format. Please upload a valid JSON file.'); setIsValidFile(false); } } catch (err) { setError('Invalid JSON format. Please upload a valid JSON file.'); setIsValidFile(false); } } else { setError('Invalid JSON format. Please upload a valid JSON file.'); setIsValidFile(false); } }; reader.onerror = () => { setError('Failed to read the file. Please try again.'); setIsValidFile(false); }; reader.readAsText(file); }; const validateHtmlFile = (file: File) => { const reader = new FileReader(); reader.onload = (e) => { const content = e.target?.result; if (typeof content === 'string' && content.includes('<html')) { setIsValidFile(true); setSuccess('Processed HTML Successfully'); setHtmlContent(content); setIsConverted(true); } else { setError('Invalid HTML file. Please upload a valid HTML file.'); setIsValidFile(false); } }; reader.onerror = () => { setError('Failed to read the file. Please try again.'); setIsValidFile(false); }; reader.readAsText(file); }; const handleFileAccept = () => { setIsLoading(true) isValidFile ? setIsConverted(true) : setError("Invalid File"); setIsLoading(false) }; const handleReportSelect = (value: string) => { if (value && reports[value]) { console.log(mockReports[value]); setSelectedReport(value); } else { setSelectedReport(null); } }; const jsonKeyValues = extractKeyValuePairs(jsonData); return ( <div> <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}> <DialogTrigger asChild> {buttonElement} </DialogTrigger> <DialogContent className="bg-white rounded-lg p-6 mx-auto shadow-lg w-full max-h-screen overflow-y-auto max-w-fit"> <DialogHeader> <DialogTitle className="text-lg font-semibold">{title}</DialogTitle> <DialogDescription className="text-sm text-gray-500"> Select an HTML or JSON file to convert it to a report format. </DialogDescription> </DialogHeader> {!isConverted && ( <div className="relative mt-4"> {!jsonFileName && ( <input type="file" accept=".json" onChange={handleJsonFileChange} className="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100" /> )} {jsonFileName && ( <div className="mt-2 text-sm text-gray-700"> <span className="font-semibold">Selected file:</span> <span className="ml-2 truncate max-w-xs inline-block" title={jsonFileName}> {jsonFileName.length > 13 ? `${jsonFileName.slice(0, 10)}...` : jsonFileName} </span> </div> )} <p>Upload JSON</p> </div> )} {!isConverted && ( <div className="relative mt-4"> {!htmlFileName && ( <input type="file" accept=".html" onChange={handleHtmlFileChange} className="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100 mt-4" /> )} {htmlFileName && ( <div className="mt-2 text-sm text-gray-700"> <span className="font-semibold">Selected file:</span> <span className="ml-2 truncate max-w-xs inline-block" title={htmlFileName}> {htmlFileName.length > 13 ? `${htmlFileName.slice(0, 10)}...` : htmlFileName} </span> </div> )} <p>Upload Html</p> </div> )} {error && <div className="mt-4 text-red-500 text-sm">{error}</div>} {success && <div className="mt-4 text-green-500 text-sm">{success}</div>} {!isConverted && (<> <div className="mt-8"> <label htmlFor="reportSelect" className="block text-sm font-medium text-gray-700"> Select a Report </label> <Select value={selectedReport || ''} onValueChange={handleReportSelect}> <SelectTrigger className="mt-1 flex items-center justify-between rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-blue-500 sm:text-sm"> <SelectValue placeholder="Select a report" /> </SelectTrigger> <SelectContent> {Object.keys(reports).map((key) => ( <SelectItem key={key} value={key}> {reports[key].title} </SelectItem> ))} </SelectContent> </Select> </div> <button onClick={handleFileAccept} disabled={!file} className={`mt-4 w-full bg-blue-500 text-white py-2 px-4 rounded-lg shadow-md ${!file ? 'opacity-50 cursor-not-allowed' : 'hover:bg-blue-600' }`} > Process File </button></> )} {isLoading && ( <div className="flex justify-center mt-4"> <svg className="animate-spin h-8 w-8 text-blue-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" > <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle> <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" ></path> </svg> </div> )} {isValidFile && isConverted && ( <div className="mt-8"> <div className="mt-4"> <label htmlFor="newFileName" className="block text-sm font-medium text-gray-700"> Name Your Report </label> <input id="newFileName" type="text" value={newFileName} onChange={handleFileNameChange} className={`mt-1 block w-full px-3 py-2 border ${fileNameError ? 'border-red-500' : 'border-gray-300' } rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm`} placeholder="Enter a valid filename" /> {fileNameError && <p className="text-red-500 text-sm mt-2">{fileNameError}</p>} </div> <ChatInterface submitButtonElement={<button className="mt-2 w-full bg-green-500 text-white py-2 px-4 rounded-lg shadow-md hover:bg-green-600">Submit</button>} title="Lets Create Some Notes For This Report" subtitle="Provide valuable context for your second brain" goal="Add Context that can help your second brian make relations" jsonKeyValues={jsonKeyValues} /> {htmlContent ? ( <div className="mt-8"> <h3 className="text-lg font-semibold">HTML Content</h3> <div className="overflow-y-auto max-h-64 max-w-full"> <WholeWord /> <HtmlThreeDeeGraphDisplay container={{ string: htmlContent }} isEditing={false} /> </div> </div> ) : ( <div className="overflow-y-auto max-h-64"> <pre className="bg-gray-800 text-white p-4 rounded-lg shadow-lg mt-4"> {JSON.stringify(jsonData, null, 2)} </pre> </div> )} <button onClick={handleFileAccept} className="mt-4 w-full bg-green-500 text-white py-2 px-4 rounded-lg shadow-md hover:bg-green-600" > Generate Report </button> </div> )} </DialogContent> </Dialog> </div> ); };
Cyber V0.01 Revision GPT FAQs
More custom GPTs by cybershoptech.com on the GPT Store
Practice (Voice) Interview Prep
Practice your job interview with this gpt 1: Start Like Normal Call Starting with "Im ready to start my interview works best Gpt Mobile voice chat or ChatGPT for ios (Voice) 2: Practice the call as normal the LLM chooses their attitude randomly.
10K+
Practice (Voice) Sales Script Mentor
Practice your sales script / rebuddles with this gpt 1: Start Like Normal calling asking for business name works best with Gpt Mobile voice chat or ChatGPT for ios (Voice) 2: Practice the call as normal the LLM chooses their attitude randomly.
100+
Free Resume Builder GPT
Creates restructured resume from
40+

Cyberoni Python Senior Dev v0.01
Cyberoni introduces the Python Code Writer v 0.01, crafted by Py, our Senior Developer. This tool showcases agile programming, optimized performance, and robust type checking. It's ideal for fast, efficient, and reliable Python coding solutions.
20+

Book Writer From Outline
Writes books from outlines
20+
React Native ONI Stack Bot
Generate precise code from text
20+
CyberOni Blog Creater v0.02
10+
Best Alternative GPTs to Cyber V0.01 Revision on GPTs Store
Ethical Hacker GPT
Cyber security specialist for ethical hacking guidance.
300K+
Cyber Scraper: Seraphina (Web Crawler)
🐍 I'm a Python Web Scraping Expert, skilled in using advanced frameworks(E.g. selenium) and addressing anti-scraping measures 😉 Let's quickly design a web scraping code together to gather data for your scientific research task 🚀
25K+
CISO AI
Team of experts assisting CISOs, CIOs, Exec Teams, and Board Directors in cyber risk oversight and security program management, providing actionable strategic, operational, and tactical support. Enhanced with advanced technical security architecture and engineering expertise.
10K+
Cyber security
Cyber security advisor for digital safety
10K+
Cyber Mentor
Cybersecurity mentor teaching from the basics to advanced.
5K+
Cyber Security Specialist
🔐 Meet the Cyber Security Specialist GPT! 🌐 Your go-to digital expert for all things cybersecurity. 🛡️ Whether you're looking to fortify your digital defenses, understand the latest in encryption, or stay ahead of cyber threats, this AI-powered specialist is here to guide you.
5K+
Cyber Threat Intelligence
An automated cyber threat intelligence expert configured and trained by Bob Gourley. Pls provide feedback. Find Bob on X at @bobgourley
5K+
Cyber Guardian
A virtual SOC analyst aiding in incident response.
5K+
Cyber Security Expert
Cyber security, information security, data security, cyber law expert
5K+
Transilience Threat Research Expert
Cyber threat intelligence specialist providing insights and specific IOCs (powered by www.transilience.ai)
1K+
Cyber Security Assistant(Bilingual )
Cybersecurity and digital forensics expert.
1K+
CyberGPT
Your #1 Cyber Security Assistant
1K+
Cyber AI Assistant
An advanced cybersecurity co-pilot, aiding in threat analysis, strategic intelligence, IoC assessment, and tailored threat modeling.
1K+
Cyber Threat Hunting and Detection Engineering
Expert in detection engineering, threat hunting, Sigma and Yara rules creation.
1K+
Cyber Security Ninja
Cyber Security Incident Assistant
1K+
Cyber Security Career Mentor
Your guide to starting and advancing in cybersecurity careers, offering beginner-friendly, practical advice.
1K+
Cyber Guard
Cybersecurity advisor for home and small businesses. Ask any question or let cyber guard interview you.
1K+
Cyber Security Tutor
Quality Cyber Security Advice, Tricks, & Tips
1K+
Cyber Sentinel
Direct, specific guidance on cybersecurity without legal advisories.
800+
Cyber Charli
Educating kids and parents about cybersecurity in a fun way!
600+
Blueteam.AI
Cyber Security Analyst, Specialized in Threat Intels and Attack Analysis.
600+