Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: migrate tools components to typescript #2774

Merged
merged 23 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ec8f1bc
migrated tools/Tags.tsx to TypeScript
devilkiller-ag Mar 14, 2024
8e3d9e6
migrated tools/CardData to typescript
devilkiller-ag Mar 14, 2024
6e066b3
migrated ToolsCard component
devilkiller-ag Mar 15, 2024
01f8f95
migrated tools list to typescript
devilkiller-ag Mar 15, 2024
07c20db
Merge branch 'migrate-ts' into ag-ts-tools
devilkiller-ag Mar 18, 2024
5b859d1
migrated CategoryDropdown to TypeScript
devilkiller-ag Mar 18, 2024
9946faa
fixed lint issues
devilkiller-ag Mar 18, 2024
f252944
migrated filter dropdown
devilkiller-ag Mar 18, 2024
1903539
migrated filter display
devilkiller-ag Mar 18, 2024
07f2f08
migrated filter component
devilkiller-ag Mar 19, 2024
1b70f5b
migrated tools dashboard
devilkiller-ag Mar 20, 2024
5bbf451
Merge branch 'migrate-ts' into ag-ts-tools
devilkiller-ag Mar 20, 2024
7b05f1d
incoporated review suggestions
devilkiller-ag Mar 27, 2024
d6a7cbc
Merge branch 'migrate-ts' into ag-ts-tools
devilkiller-ag Mar 27, 2024
6e85813
fixed lint issue
devilkiller-ag Mar 27, 2024
691bb8b
Merge branch 'migrate-ts' into ag-ts-tools
akshatnema Mar 27, 2024
911b372
added comments:
devilkiller-ag Mar 27, 2024
eb99304
Merge branch 'ag-ts-tools' of https://github.com/devilkiller-ag/async…
devilkiller-ag Mar 27, 2024
84ab865
fix lint issue
devilkiller-ag Mar 27, 2024
eb4c2bc
Merge branch 'migrate-ts' into ag-ts-tools
akshatnema Mar 27, 2024
89304b6
restored the original categorylist in scripts/tool
devilkiller-ag Mar 29, 2024
55feac3
Merge branch 'migrate-ts' into ag-ts-tools
devilkiller-ag Mar 29, 2024
6c5bd6f
Updated import
akshatnema Mar 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions components/tools/CardData.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import React, { useEffect, useRef, useState } from 'react';
import TextTruncate from 'react-text-truncate';

import InfoIcon from '../icons/InfoIcon';

type VisibleType = Record<string, boolean>;

interface CardDataProps {
className: string;
visible: VisibleType;
heading: string;
data: string;
read: boolean;
setRead: React.Dispatch<React.SetStateAction<boolean>>;
setVisible: React.Dispatch<React.SetStateAction<VisibleType>>;
type: string;
};

/**
* @description This component displays Card.
*
* @param {SelectTagsProps} props - The props for the Cards Data component.
* @param {string} props.className - Additional CSS classes for the component.
* @param {VisibleType} props.visible - Visibility status for different types.
* @param {string} props.heading - The heading text.
* @param {string} props.data - The data to be displayed.
* @param {boolean} props.read - Read status.
* @param {React.Dispatch<React.SetStateAction<boolean>>} props.setRead - Function to set read status.
* @param {React.Dispatch<React.SetStateAction<VisibleType>>} props.type - Function to set visibility status.
*/
export const CardData = ({
className,
visible,
heading,
data,
read,
setRead,
setVisible,
type
}: CardDataProps) => {
const [outsideClick, setOutsideClick] = useState<boolean>(true);
const [description, setShowDescription] = useState<boolean>(false);
const initial = {
lang: false,
tech: false,
category: false,
pricing: false,
ownership: false
};
const domNode = useRef<HTMLSpanElement>(null);

useEffect(() => {
const divHeight = domNode.current?.offsetHeight || 0;
const numberOfLines = divHeight / 20;

if (numberOfLines > 3) {
setShowDescription(true);
} else {
setShowDescription(false);
}
}, [visible]);
akshatnema marked this conversation as resolved.
Show resolved Hide resolved

useEffect(() => {
const maybeHandler = (event: MouseEvent) => {
setOutsideClick(true);
if (domNode.current && !domNode.current.contains(event.target as Node)) {
setOutsideClick(false);
}
};

document.addEventListener('mousedown', maybeHandler);

return () => {
document.removeEventListener('mousedown', maybeHandler);
};
}, []);
akshatnema marked this conversation as resolved.
Show resolved Hide resolved

return (
<div className={className || 'text-left text-sm text-gray-500'}>
{heading}
<span className='group relative'>
{outsideClick && visible[type] && (
<span
ref={domNode}
data-testid='Carddata-description'
className='absolute -left-2/3 -top-4 z-10 w-48 translate-x-1/3 rounded border border-gray-200
bg-white px-2 py-1 text-xs shadow-md'
>
{read ? (
data
) : (
<div>
<TextTruncate element='span' line={4} text={data} />
</div>
)}
{description && (
<button
className='cursor-pointer text-cyan-600'
onClick={() => {
setOutsideClick(true);
setRead(!read);
}}
>
{read ? ' Show Less' : ' Show More'}
</button>
)}
</span>
)}
<button
onClick={() => {
setRead(false);
setVisible({ ...initial, [type]: !visible[type] });
}}
className='mx-1'
data-testid='Carddata-button'
>
<InfoIcon />
</button>
</span>
</div>
);
};
35 changes: 35 additions & 0 deletions components/tools/CategoryDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { ToolsListType } from '@/types/components/tools/ToolDataType';

import ToolsDataList from '../../config/tools.json';

interface CategoryDropdownProps {
setopenCategory: React.Dispatch<React.SetStateAction<boolean>>;
};

const ToolsData = ToolsDataList as ToolsListType;

/**
* @description This component displays Category Dropdown.
*
* @param {React.Dispatch<React.SetStateAction<boolean>>} props.setopenCategory - Function to set dropdown status.
*/
export default function CategoryDropdown({ setopenCategory }: CategoryDropdownProps) {
return (
<div className='absolute z-10 h-60 w-52 origin-top-right overflow-y-auto rounded-md bg-white shadow-lg ring-1 ring-black/5 focus:outline-none lg:w-56' role='menu' aria-orientation='vertical' aria-labelledby='menu-button'
data-testid='CategoryDropdown-div'>
<div className='py-1' role='none'>
{Object.keys(ToolsData).map((categoryName, index) => {
// displaying tools category having atleast one tool
if (ToolsData[categoryName].toolsList.length > 0) {
return (
<div key={index} onClick={() => setopenCategory(false)}>
<a href={`#${categoryName}`} key={index} className='block px-4 py-2 hover:bg-gray-100' data-testid='CategoryDropdown-link'>{categoryName}</a>
</div>);
}

akshatnema marked this conversation as resolved.
Show resolved Hide resolved
return null;
})}
</div>
</div>
);
};
48 changes: 48 additions & 0 deletions components/tools/FilterDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { twMerge } from 'tailwind-merge';

interface FiltersDisplayProps {
checkedOptions?: string[];
setCheckedOptions: React.Dispatch<React.SetStateAction<string[]>>;
};

/**
* @description This component displays Filters.
*
* @param {string[]} props.checkedOptions - List of options that are currently checked.
* @param {React.Dispatch<React.SetStateAction<string[]>>} props.setCheckedOptions - Function to set check state of options.
*/
export default function FiltersDisplay({
checkedOptions = [],
setCheckedOptions
}: FiltersDisplayProps) {
// function to clear selected filters
const handleClickOption = (event: React.MouseEvent, option: string, checkedOptionsList: typeof checkedOptions, setCheckedOptionsList: typeof setCheckedOptions) => {
const tempValueArray = [...checkedOptionsList];
const index = checkedOptionsList.indexOf(option);

if (index > -1) {
tempValueArray.splice(index, 1);
}
setCheckedOptionsList(tempValueArray);
};

return (
<>
{checkedOptions.length > 0 &&
<div className='flex max-w-lg flex-wrap gap-2 p-2 delay-150 duration-200' data-testid='FiltersDisplay-main'>
{checkedOptions.map((items, index) => {
return (
<div
key={index}
className={twMerge('hover:border-black border border-gray-600 text-gray-600 hover:text-black p-1 pb-0 rounded-2xl flex gap-1 items-start')}
>
<div className='m-auto h-fit text-xs'>{items}</div>
<button className='mt-[-2px] rounded-full p-1 hover:bg-gray-100' onClick={(event) => handleClickOption(event, items, checkedOptions, setCheckedOptions)} data-testid='Filters-Display-Button'>
<img src='/img/illustrations/icons/close-icon.svg' alt='close' width='10' /></button>
</div>
);
})}
</div>}
</>
);
};
57 changes: 57 additions & 0 deletions components/tools/FiltersDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { twMerge } from 'tailwind-merge';

interface DataListType {
name: string;
color: string;
borderColor: string;
};

interface FiltersDropdownProps {
dataList?: DataListType[];
checkedOptions?: string[];
setCheckedOptions: React.Dispatch<React.SetStateAction<string[]>>;
className?: string;
};

/**
* @description This component displays Filter Dropdown Component.
*
* @param {DataListType[]} props.dataList - List of filter options.
* @param {string[]} props.checkedOptions - List of options that are currently checked.
* @param {React.Dispatch<React.SetStateAction<string[]>>} props.setCheckedOptions - Function to set check state of options.
* @param {string} props.className - Additional CSS classes for the component.
*/
export default function FiltersDropdown({
dataList = [],
checkedOptions = [],
setCheckedOptions,
className = ''
}: FiltersDropdownProps) {
const handleClickOption = (event: React.MouseEvent, option: string) => {
akshatnema marked this conversation as resolved.
Show resolved Hide resolved
const isChecked = checkedOptions.includes(option);
const updatedOptions = isChecked
? checkedOptions.filter(item => item !== option)
: [...checkedOptions, option];

setCheckedOptions(updatedOptions);
};

return (
<div className={twMerge(`max-w-lg flex gap-2 flex-wrap p-2 duration-200 delay-150 ${className}`)} data-testid='FiltersDropdown-div'>
{dataList.map((data, index) => {
const checked = checkedOptions.includes(data.name);

return (
<div
key={index}
className={twMerge(`border border-secondary-600 text-secondary-600 p-1 pb-0 rounded-2xl flex gap-1 cursor-pointer items-start ${checked ? 'bg-secondary-600 text-white' : ''}`)}
onClick={(event) => handleClickOption(event, data.name)}
>
{checked ? <img src='/img/illustrations/icons/CheckedIcon.svg' alt='checked' /> : <img src='/img/illustrations/icons/UncheckedIcon.svg' alt='unchecked' />}
<div className='mb-[1px] mt-[-1px] text-xs'>{data.name}</div>
</div>
);
})}
</div>
);
};
25 changes: 25 additions & 0 deletions components/tools/Tags.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
interface SelectTagsProps {
name?: string;
bgColor: string;
borderColor: string;
};

/**
* @description This component displays tags.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Describe these tags more, on where it is used.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

*
* @param {SelectTagsProps} props - The props for the Select Tags component.
* @param {string} props.name - The content to be displayed inside the tag.
* @param {string} props.bgColor - The color of the tag.
* @param {string} props.borderColor - The border color of the tag.
*/
export default function SelectTags({
name = '',
bgColor,
borderColor
} : SelectTagsProps) {
return (
<div className={`rounded-lg px-2 py-1 text-center text-sm ${bgColor} border ${borderColor}`} data-testid='Tags-main'>
{name}
</div>
);
};
Loading
Loading