Skip to content

Commit

Permalink
Merge pull request #5 from wizeline/feat/GL-52/lading-design-modal-info
Browse files Browse the repository at this point in the history
feat: [GL-52] Added lading design modal info
  • Loading branch information
raulMarvanWizeline authored Mar 23, 2024
2 parents c5df0ac + dcbe1d2 commit b06df93
Show file tree
Hide file tree
Showing 11 changed files with 310 additions and 38 deletions.
44 changes: 27 additions & 17 deletions app/components/charts/SunburstChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useEffect, useRef, useState } from "react";
import * as d3 from "d3";
import { useScreenSize } from "~/context/ScreenSizeContext";
import ModalInformation from "../information/ModalInformation";
import { NodeType } from "~/types";

export type SunburstLeaf = {
name: string;
Expand All @@ -25,24 +28,21 @@ const SunburstChart = (props: SunburstElementProps) => {
const color = d3.scaleOrdinal(d3.schemeSet1);
const chartRef = useRef<HTMLDivElement | null>(null);
const [Sunburst, setSunburst] = useState<any | null>(null);
const [selectedNode, setSelectedNode] = useState<any | null>(null);
const [selectedNode, setSelectedNode] = useState<NodeType | null>(null);
const [hasChildNodes, setHasChildNodes] = useState(false);
const [isInfoModalOpen, setIsInfoModalOpen] = useState(false);
const { isDesktop, isTablet } = useScreenSize();
const chartWidth = isDesktop ? 800 : isTablet ? 600 : 300;

const handleIsInfoModalOpen = () => {
setIsInfoModalOpen(true);
};

const handleIsInfoModalClose = () => {
setSelectedNode(null);
setIsInfoModalOpen(false);
};

console.log({
isInfoModalOpen,
handleIsInfoModalClose,
handleIsInfoModalOpen,
});

useEffect(() => {
if (chartRef.current) {
const observer = new MutationObserver((mutationsList) => {
Expand Down Expand Up @@ -70,29 +70,39 @@ const SunburstChart = (props: SunburstElementProps) => {
useEffect(() => {
if (data && Sunburst && !hasChildNodes) {
const chart = Sunburst();

chart
.data(data)
.label("name")
.labelOrientation("angular")
.maxLevels(10)
.color((d: any, parent: any) => color(parent ? parent.data.name : null))
.onHover((node: any) => {
setSelectedNode(node);
if (node) {
setSelectedNode(node);
}
if (!isInfoModalOpen) {
handleIsInfoModalOpen();
}
})
.width(800)
.width(chartWidth)
.tooltipContent((d: any, node: any) => `Size: <i>${node.value}</i>`)(
chartRef.current
);
}
}, [data, Sunburst, color, hasChildNodes]);

useEffect(() => {
if (selectedNode) {
console.log(selectedNode);
}
}, [selectedNode]);
}, [data, Sunburst, color, hasChildNodes, chartWidth, isInfoModalOpen]);

return <div ref={chartRef} className="max-w-[800px] z-0"></div>;
return (
<>
<div ref={chartRef} className="max-w-[800px] z-0"></div>
{isInfoModalOpen && selectedNode && (
<ModalInformation
onClose={handleIsInfoModalClose}
node={selectedNode}
/>
)}
</>
);
};

export default SunburstChart;
15 changes: 15 additions & 0 deletions app/components/common/Pill.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { FC } from "react";

interface PillProps {
children: React.ReactNode;
}

const Pill: FC<PillProps> = ({ children }) => {
return (
<span className="inline-flex items-center px-3 py-1 text-sm font-medium rounded-full bg-[#E93D44] text-white gap-2">
{children}
</span>
);
};

export default Pill;
144 changes: 144 additions & 0 deletions app/components/information/ModalInformation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { OpenInNew } from "@mui/icons-material";
import CloseIcon from "@mui/icons-material/Close";
import { IconButton } from "@mui/material";
import { FC } from "react";
import { NodeType } from "~/types";
import Pill from "../common/Pill";

interface ModalInformationProps {
node: NodeType | null;
onClose: () => void;
}

const ModalInformation: FC<ModalInformationProps> = ({ node, onClose }) => {
// TODO - Replace information with actual data from the node
const features = [
"Integrations to connect Fireflies with other meeting platforms like Google Meet, Zoom, Microsoft Teams, Skype, and more.",
"Rich text editing features to correct, comment, annotate, and format transcripts as needed.",
"Smart summaries to grab the key points, next steps, questions, and discussion highlights from your meeting.",
"Search and organization features to isolate words, phrases, and topics in your transcripts.",
];
const tools = [
"ClickUp",
"ChatGPT",
"Jasper",
"Spinach",
"GrammarlyGO",
"Figstack",
];

return (
<div className="fixed top-4 right-4 w-96 h-auto max-h-[90vh] bg-secondary rounded-md p-2 gap-2 overflow-auto z-50">
<div className="flex justify-between items-center mb-2">
<h2 className="text-white border border-primary p-4 mr-2 w-full rounded-md">
{node?.name}
</h2>
<div className="border border-primary rounded-md p-4">
<IconButton className="!p-0" onClick={onClose}>
<CloseIcon className="!fill-white" />
</IconButton>
</div>
</div>
<a href="https://fireflies.ai/" target="_blank" rel="noreferrer">
<div className="border border-primary rounded-md p-2 mb-2 flex justify-between p-4 items-center">
<p className="text-blue500 font-montserrat font-medium text-sm leading-[18px]">
Fireflies.ai
</p>
<OpenInNew className="!fill-primary" />
</div>
</a>
<div className="border border-primary rounded-md p-4 mb-2 grid grid-cols-2 gap-4">
<div>
<h3 className="font-bold text-[12px] leading-[16px] text-blue300 mb-2">
Company
</h3>
<p className="font-normal text-[14px] leading-[18px] text-white-alt">
Fireflies.ai Corp.
</p>
</div>
<div>
<h3 className="font-bold text-[12px] leading-[16px] text-blue300 mb-2">
AI Model
</h3>
<p className="font-normal text-[14px] leading-[18px] text-white-alt">
Data and Integration Services
</p>
</div>
<div>
<h3 className="font-bold text-[12px] leading-[16px] text-blue300 mb-2">
Category
</h3>
<p className="font-normal text-[14px] leading-[18px] text-white-alt">
Data and Simulation Generation
</p>
</div>
<div>
<h3 className="font-bold text-[12px] leading-[16px] text-blue300 mb-2">
Industry
</h3>
<p className="font-normal text-[14px] leading-[18px] text-white-alt">
Customer Segmentation
</p>
</div>
</div>
<div className="border border-primary rounded-md p-4 mb-2">
<h3 className="font-bold text-[12px] leading-[16px] text-blue300 mb-2">
About
</h3>
<p className="font-normal text-[14px] leading-[18px] text-white-alt mb-4">
Fireflies is an AI meeting assistant software for note-taking and
transcribing voices in real-time. Whether you’re in the midst of a
brainstorming session or uploading files from a customer interview,
Fireflies can instantly capture your conversations in writing.{" "}
</p>
<p className="font-normal text-[14px] leading-[18px] text-white-alt">
Regardless of accent, dialect, industry, or language, this meeting
assistant can detect even the smallest differences in speech for
precise transcriptions on the first try.{" "}
</p>
</div>
<div className="border border-primary rounded-md p-4 mb-2">
<h3 className="font-bold text-[12px] leading-[16px] text-blue300 mb-2">
Best features
</h3>
<div className="font-normal text-[14px] leading-[18px] text-white-alt pl-4">
<ul className="list-disc">
{features.map((feature, index) => (
<li key={`${feature}-${index}`}>{feature}</li>
))}
</ul>
</div>
</div>
<div className="border border-primary rounded-md p-4 mb-2">
<h3 className="font-bold text-[12px] leading-[16px] text-blue300 mb-2">
Pricing
</h3>
<p className="text-[14px] leading-[18px] text-white-alt">
<span className="font-bold">Personal:</span>
<span className="font-normal"> Free</span>
</p>
<p className="text-[14px] leading-[18px] text-white-alt">
<span className="font-bold">Professional:</span>
<span className="font-normal"> $10 per month</span>
</p>
<p className="text-[14px] leading-[18px] text-white-alt">
<span className="font-bold">Team:</span>
<span className="font-normal"> $20 per user, per month</span>
</p>
</div>
<div className="border border-primary rounded-md p-4 mb-2">
<h3 className="font-bold text-[12px] leading-[16px] text-blue300 mb-2">
Related tools
</h3>
<div className="flex flex-wrap gap-2">
{tools.map((tool, index) => (
<Pill key={`${tool}-${index}`}>{tool}</Pill>
))}
</div>
</div>
</div>
);
};

export default ModalInformation;
38 changes: 38 additions & 0 deletions app/context/ScreenSizeContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { FC, createContext, useContext } from "react";
import { useMediaQuery } from "react-responsive";

interface ScreenSizeContextProps {
isDesktop: boolean;
isTablet: boolean;
isMobile: boolean;
}

const ScreenSizeContext = createContext<ScreenSizeContextProps | undefined>(
undefined
);

interface ScreenSizeProviderProps {
children: React.ReactNode;
}

export const ScreenSizeProvider: FC<ScreenSizeProviderProps> = ({
children,
}) => {
const isDesktop = useMediaQuery({ minWidth: 1024 });
const isTablet = useMediaQuery({ minWidth: 768, maxWidth: 1023 });
const isMobile = useMediaQuery({ maxWidth: 767 });

return (
<ScreenSizeContext.Provider value={{ isDesktop, isTablet, isMobile }}>
{children}
</ScreenSizeContext.Provider>
);
};

export const useScreenSize = () => {
const context = useContext(ScreenSizeContext);
if (context === undefined) {
throw new Error("useScreenSize must be used within a ScreenSizeProvider");
}
return context;
};
5 changes: 4 additions & 1 deletion app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ScrollRestoration,
} from "@remix-run/react";
import "./tailwind.css";
import { ScreenSizeProvider } from "./context/ScreenSizeContext";

export function Layout({ children }: { children: React.ReactNode }) {
return (
Expand All @@ -18,7 +19,9 @@ export function Layout({ children }: { children: React.ReactNode }) {
<Links />
</head>
<body>
{children}
<ScreenSizeProvider>
{children}
</ScreenSizeProvider>
<ScrollRestoration />
<Scripts />
</body>
Expand Down
2 changes: 1 addition & 1 deletion app/routes/_index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default function Index() {
{
id: 1,
description: "ClickUp now is included as an AI Coding Tool",
date: "2024-03-23T00:00:00.000Z",
date: "2025-03-23T00:00:00.000Z",
},
{
id: 2,
Expand Down
1 change: 1 addition & 0 deletions app/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
// src/types/index.ts
export * from "./notificationTypes";
export * from "./nodeTypes";
20 changes: 20 additions & 0 deletions app/types/nodeTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export type NodeType = {
name: string;
value: number;
__dataNode: DataNodeType;
};

export type DataNodeType = {
__dataNode: DataNodeType;
data: NodeType;
depth: number;
height: number;
id: number;
parent: NodeType | null;
children: NodeType[] | null;
value: number;
x0: number;
x1: number;
y0: number;
y1: number;
};
Loading

0 comments on commit b06df93

Please sign in to comment.