-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #58 from wlee261/feat/themes-page-implementation
feat: themes page implementation
- Loading branch information
Showing
9 changed files
with
342 additions
and
244 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
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
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
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 |
---|---|---|
@@ -1,91 +1,87 @@ | ||
import React, { useState } from 'react'; | ||
import React, { useState } from "react"; | ||
|
||
import { Link } from 'react-router-dom'; | ||
import Skeleton from "react-loading-skeleton"; | ||
|
||
import ThemeModal from './ThemeModal'; | ||
import { Theme } from '../../interfaces/Theme'; | ||
import FavIcon from '../../assets/images/icon_favorite.svg'; | ||
import GitHubIcon from '../../assets/images/icon_github_white.svg'; | ||
import { Theme } from "../../interfaces/Theme"; | ||
import { useTranslation } from 'react-i18next'; | ||
import '../../styles/theme_card.css' | ||
import "../../styles/theme_card.css"; | ||
import ThemeModal from "./ThemeModal"; | ||
import { InfoIcon } from "lucide-react"; | ||
|
||
type Props = { | ||
theme: Theme | ||
isPreviewed: boolean | ||
onPreview: (name: string) => void | ||
} | ||
theme: Theme; | ||
isPreviewed: boolean; | ||
onPreview: (name: string) => void; | ||
isLoading: boolean; | ||
}; | ||
|
||
/** | ||
* Theme card component to hold the details of each theme in the themes page. | ||
*/ | ||
const ThemeCard: React.FC<Props> = ({ theme, isPreviewed, onPreview }) => { | ||
const [isFav, setIsFav] = useState(false) | ||
const [viewDetails, setViewDetails] = useState(false) | ||
const ThemeCard: React.FC<Props> = ({ theme, isPreviewed, onPreview, isLoading }) => { | ||
const [viewDetails, setViewDetails] = useState(false); | ||
|
||
const onViewDetails = () => { | ||
setViewDetails(true) | ||
} | ||
setViewDetails(true); | ||
}; | ||
|
||
const onClickPreview = () => { | ||
onPreview(theme.name) | ||
} | ||
|
||
const handleCheckboxChange = () => { | ||
onClickPreview(); | ||
}; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
const {t} = useTranslation(); | ||
|
||
if (isLoading) { | ||
return ( | ||
<div> | ||
<div className="my-4 mx-2 hidden md:block"> | ||
<Skeleton height={452} /> | ||
</div> | ||
<div className="my-4 mx-2 block md:hidden"> | ||
<Skeleton height={148} /> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
return ( | ||
<> | ||
<div className="text-black w-[300px] h-[545px]"> | ||
<button | ||
onClick={onViewDetails} | ||
type="button" | ||
className="relative group" | ||
<div | ||
className={`flex flex-row items-center md:items-start md:flex-col | ||
md:w-64 p-4 my-4 mx-2 border-2 border-solid rounded-xl | ||
${isPreviewed ? "border-blue-700" : "border-accent-600"}`} | ||
> | ||
<div | ||
className="flex-1 basis-1/3 md:basis-1/2 mr-3 flex flex-row | ||
overflow-hidden w-32 h-20 md:w-56 md:h-56 rounded-xl" | ||
> | ||
<img | ||
src={theme.themeImg} | ||
className="cursor-pointer w-full h-[400px] scale-80 | ||
group-hover:-translate-y-6 transition ease-in-out duration" | ||
alt={theme.name} | ||
/> | ||
<div className="theme-card-details">View Details</div> | ||
</button> | ||
<div className="theme-card-info"> | ||
<div> | ||
<div className="flex justify-between"> | ||
<p className="theme-card-title">{theme.name}</p> | ||
<button | ||
type="button" | ||
aria-label="Favorite Button" | ||
className={`theme-card-fav ${isFav && 'active'}`} | ||
onClick={() => setIsFav((fav) => !fav)} | ||
> | ||
<img src={FavIcon} alt="fav-icon" /> | ||
</button> | ||
</div> | ||
<p className="text-[15px] opacity-80">{theme.description}</p> | ||
</div> | ||
<Link to={`/profile/${theme.github}`} className="theme-card-github"> | ||
<img src={GitHubIcon} alt="github-icon" /> | ||
</Link> | ||
<div className="flex justify-between"> | ||
<h4 className="theme-card-author">{theme.authorName}</h4> | ||
<button | ||
className={`theme-card-preview ${isPreviewed ? 'active' : ''}`} | ||
type="button" | ||
onClick={onClickPreview} | ||
> | ||
Preview | ||
<img src={theme.themeImg} alt={theme.name} className="w-60 h-60 object-cover object-left-top" /> | ||
</div> | ||
<div className="flex-1 mr-4 basis-1/2 md:basis-1/3 flex flex-col md:pt-4"> | ||
<h2 className="text-accent-50 text-lg font-medium mt-[-4px]">{theme.name}</h2> | ||
<span className="text-accent-300 text-sm">{theme.description}</span> | ||
</div> | ||
<div className="flex-1 basis-1/6 md:basis-1/6 flex flex-col"> | ||
<div className="flex items-center text-blue-500"> | ||
<button onClick={onViewDetails} className="text-sm my-4 w-fit mr-[3px]"> | ||
More Info | ||
</button> | ||
<InfoIcon size={15}/> | ||
</div> | ||
<label className=" ml-[2px] text-accent-50 text-sm md:text-base"> | ||
Select | ||
<input type="checkbox" checked={isPreviewed} onChange={handleCheckboxChange} className="ml-2" /> | ||
</label> | ||
</div> | ||
</div> | ||
<ThemeModal | ||
isOpen={viewDetails} | ||
theme={theme} | ||
onClose={() => setViewDetails(false)} | ||
/> | ||
<ThemeModal isOpen={viewDetails} theme={theme} onClose={() => setViewDetails(false)} /> | ||
</> | ||
) | ||
} | ||
); | ||
}; | ||
|
||
export default ThemeCard | ||
export default ThemeCard; |
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.