-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
28350a6
commit bd4064b
Showing
5 changed files
with
425 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import Image from "next/image"; | ||
|
||
import deepchemCross from "../../public/icons/deepchem-cross.png"; | ||
|
||
/** | ||
* The FilterButton component is used to create a button for each filter | ||
* @component | ||
* @param {Object} props - props passed to the component | ||
* @param {Array} props.category - array of all the available filters | ||
* @param {String} props.name - name of the particular filter | ||
* @param {Image} props.image - image associated to the filter | ||
* @return {JSX.Element} - A JSX element representing the FilterButton | ||
*/ | ||
const FilterButton = ({ category, name, image }) => { | ||
const TRUNC_LENGTH = 20; | ||
const nameShort = name.replace(/Model$/g, ""); | ||
|
||
return ( | ||
<> | ||
<div | ||
className={`${ | ||
category.includes(name) ? "btn-selected-filter" : "btn-filter" | ||
}`} | ||
title={name} | ||
> | ||
{image ? ( | ||
<Image | ||
src={category.includes(name) ? deepchemCross : image} | ||
alt={name} | ||
width={14} | ||
/> | ||
) : ( | ||
category.includes(name) && ( | ||
<Image src={deepchemCross} alt={name} width={14} /> | ||
) | ||
)} | ||
<p | ||
className={`${ | ||
category.includes(name) | ||
? "btn-text-selected-filter" | ||
: "btn-text-filter" | ||
}`} | ||
> | ||
{nameShort.length > TRUNC_LENGTH | ||
? nameShort.substring(0, TRUNC_LENGTH) + "..." | ||
: nameShort} | ||
</p> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default FilterButton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import Image from "next/image"; | ||
import Link from "next/link"; | ||
|
||
import deepchemPytorch from "../../public/icons/deepchem-pytorch.png"; | ||
import deepchemKeras from "../../public/icons/deepchem-keras.png"; | ||
|
||
/** | ||
* Function to parse and format strings that are passed to the model card | ||
* @function | ||
* @param {string} name - string of the name passed | ||
* @return {string} - The parsed and formatted string | ||
*/ | ||
function parseName(name) { | ||
name = name.replaceAll(/([A-Z]+)/g, " $1"); | ||
name = name.replace(/([^ ])(Layer)/, "$1 Layer"); | ||
return name; | ||
} | ||
|
||
const LayerCard = ({ layer }) => { | ||
let models = layer.models.length | ||
? layer.models.join(", ") | ||
: "N/A"; | ||
models = models + " " + "\xa0".repeat(300); | ||
|
||
return ( | ||
<> | ||
<Link href={layer.url} target="_blank"> | ||
<div className="flex flex-col gap-4 py-4 px-5 bg-white shadow-[0_4px_4px_rgba(0,0,0,0.25)] rounded-[10px] layer-card hover:scale-[1.03] transition-all"> | ||
<div className="flex flex-row justify-between w-full gap-8 items-start"> | ||
<div className="text-xl font-medium text-dc-orange"> | ||
{parseName(layer.name)} | ||
</div> | ||
<div className="flex flex-row items-center gap-1.5 bg-dc-light-blue/5 px-2 py-1 rounded-md"> | ||
{layer.category === "torch" && ( | ||
<Image src={deepchemPytorch} alt="PyTorch" width={16} /> | ||
)} | ||
{layer.category === "keras" && ( | ||
<Image src={deepchemKeras} alt="Keras" width={16} /> | ||
)} | ||
</div> | ||
<div className="font-medium text-sm text-dc-gray"> | ||
{layer.category} | ||
</div> | ||
</div> | ||
{ | ||
<div className="text-base font-medium text-dc-light-blue w-full mt-4 md:mt-auto"> | ||
<p className="text-dc-gray/60">Acceptable Models</p> | ||
<p className="text-xs text-dc-gray font-medium break-all"> | ||
{models} | ||
</p> | ||
</div> | ||
} | ||
</div> | ||
</Link> | ||
</> | ||
); | ||
}; | ||
|
||
export default LayerCard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
import React, { useEffect, useState } from "react"; | ||
|
||
import Image from "next/image"; | ||
|
||
import LayerCard from "/components/Layers/LayerCard"; | ||
import FilterButton from "/components/Layers/FilterButton"; | ||
|
||
import layers from "/data/layers/layers.json"; | ||
import modelList from "/data/layers/models.json"; | ||
|
||
import deepchemPyTorch from "/public/icons/deepchem-pytorch.png"; | ||
import deepchemKeras from "/public/icons/deepchem-keras.png"; | ||
import deepchemFilter from "/public/icons/deepchem-filter.png"; | ||
|
||
|
||
/** | ||
* Models component that displays the models page of the application | ||
* @component | ||
* @return {JSX.Element} The JSX element to render the Model component | ||
*/ | ||
const Layers = () => { | ||
|
||
const [filteredLayers, setFilteredLayers] = useState(layers); | ||
const [models, setModels] = useState([]); | ||
const [isPopUp, setIsPopUp] = useState(false); | ||
|
||
const handleClick = (category, value) => { | ||
switch (category) { | ||
case "models": | ||
models.includes(value) | ||
? setModels(models.filter((item) => item !== value)) | ||
: setModels([...models, value]); | ||
break; | ||
default: | ||
break; | ||
} | ||
}; | ||
|
||
const handlePopUp = () => { | ||
setIsPopUp(!isPopUp); | ||
}; | ||
|
||
useEffect(() => { | ||
let newlayers = []; | ||
const flayers = layers; | ||
if ( | ||
models.length === 0 | ||
) { | ||
newlayers = layers; | ||
} else { | ||
flayers.map((flayer) => { | ||
let exist = 1; | ||
models.map((value) => { | ||
if (!flayer.models.includes(value)) { | ||
exist = 0; | ||
} | ||
}); | ||
if (exist == 1) { | ||
newlayers.push(flayer); | ||
} | ||
}); | ||
} | ||
|
||
setFilteredLayers(newlayers); | ||
}, [models]); | ||
|
||
useEffect(() => { | ||
window.addEventListener("resize", () => { | ||
if (window.innerWidth > 1024) { | ||
setIsPopUp(false); | ||
} | ||
}); | ||
}, []); | ||
|
||
return ( | ||
|
||
<div className="layers"> | ||
<div | ||
className={`${ | ||
isPopUp ? "flex" : "hidden" | ||
} fixed bg-dc-gray/80 w-full h-[100vh] top-0 lg:hidden`} | ||
onClick={handlePopUp} | ||
></div> | ||
<div className= "flex flex-col items-start w-full px-[25px] 2xl:px-[300px] py-8 lg:py-16 gap-6"> | ||
{/* HEADING BEGIN */} | ||
<div className="flex flex-row w-[100%] items-center justify-between py-2.5"> | ||
<div className="lg:text-4xl text-[26px]">Our Layers</div> | ||
<div className="lg:hidden"> | ||
<button className="min-w-0" onClick={handlePopUp}> | ||
<Image src={deepchemFilter} alt={"Filter Button"} width={18} /> | ||
</button> | ||
</div> | ||
{/* HEADING END */} | ||
{/* BODY BEGIN */} | ||
<div className="flex flex-row items-start gap-12 w-full"> | ||
{/* FILTER SECTION BEGIN */} | ||
<div | ||
className={`${ | ||
isPopUp | ||
? "fixed flex left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 px-8 py-6 bg-white shadow-[0_4px_4px_rgba(0,0,0,0.25)] rounded-[10px] w-[89%] overflow-y-auto h-[85vh]" | ||
: "hidden" | ||
} lg:flex lg:relative lg:left-0 lg:top-0 lg:translate-x-0 lg:translate-y-0 lg:shadow-none lg:rounded-none flex-col items-start gap-5 lg:min-w-[240px] lg:max-w-[240px] lg:border-r-2 lg:py-0 lg:pl-0 pr-4 lg:border-dc-light-gray`} | ||
></div> | ||
{/* MODEL BEGIN */} | ||
<div className="category-filter"> | ||
<div className="category-text-filter">Model</div> | ||
<div className="btn-container-filter"> | ||
{modelList.map((model, index) => ( | ||
<div key={`feat-${index}`}> | ||
<button | ||
className="rmv-filter" | ||
onClick={() => { | ||
handleClick("models", model); | ||
}} | ||
> | ||
<FilterButton | ||
category={models} | ||
name={model} | ||
image={null} | ||
/> | ||
</button> | ||
</div> | ||
))} | ||
</div> | ||
</div> | ||
{/* MODEL END */} | ||
{/* LAYER CARDS SECTION BEGIN */} | ||
<div | ||
className={`items-start ${ | ||
filteredLayers.length | ||
? "gap-8 justify-center layer-container" | ||
: "" | ||
} w-full`} | ||
> | ||
{filteredLayers.length ? ( | ||
filteredLayers.map((layer) => ( | ||
<LayerCard key={layer.id} layer={layer} /> | ||
)) | ||
) : ( | ||
<div className="w-full mt-[5vh] flex items-center flex-col flex-grow"> | ||
<i className="fa-solid fa-triangle-exclamation text-7xl text-dc-gray/10 mb-2"></i> | ||
<p className="text-dc-gray/60">No such layers exist!</p> | ||
</div> | ||
)} | ||
</div> | ||
{/* MODEL CARDS SECTION END */} | ||
</div> | ||
{/*BODY END*/} | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Layers; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.