Skip to content

[MathPow] Added Favorite Templates #93

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

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
81 changes: 70 additions & 11 deletions frontend/app/select-template/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,67 @@
"use client"

import { useState } from "react"
import Link from "next/link"
import { IPageType, ITemplate } from "@/api/generated"
import { FilePlus2 } from "lucide-react"

import { Button } from "@/components/ui/button"
import Card from "@/components/SelectTemplate/Card"
import SelectTemplateSideBar from "@/components/SelectTemplate/Sidebar/Sidebar"
import { FilePlus2 } from "lucide-react"
import Link from "next/link"

export default function IndexPage() {
const [template, setTemplates] = useState<ITemplate[]>([])
const [pageType, setPageType] = useState<IPageType>(IPageType.NONE)

function getTemplateId(template: ITemplate): string {
Copy link
Owner

Choose a reason for hiding this comment

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

16-64, This code can most likely be split up into a helper function, so it's easier to refactor and not as tightly coupled within the application. getSortedTemplatesByFavorite makes sense to stay here though if you want. unless you make a functional map component.

I would move this to /frontend/utils

Copy link
Owner

@ShaanCoding ShaanCoding May 6, 2024

Choose a reason for hiding this comment

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

Also for me to test later: What happens if the key isn't valid i.e. template with key no longer exists

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea. I will move it there later this week thanks

Copy link
Owner

Choose a reason for hiding this comment

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

Hey just following up on this PR, branches have diverged quite a bit.

I'm happy to do the cleanup here if you don't have the time, or would you have time available to do the above changes?

return template.title + template.dateCreated
}

function getFavoriteTemplates(): string[] {
const favoriteTemplatesJson = localStorage.getItem("favoriteTemplates")
if (favoriteTemplatesJson) {
return JSON.parse(favoriteTemplatesJson) as string[]
} else {
return []
}
}

function isFavoriteTemplate(templateId: string): boolean {
const favoriteTemplates = getFavoriteTemplates()
return favoriteTemplates.includes(templateId)
}

function toggleFavoriteTemplate(templateId: string): void {
const favoriteTemplates = getFavoriteTemplates()
if (!favoriteTemplates.includes(templateId)) {
console.log(template)
favoriteTemplates.push(templateId)
localStorage.setItem(
"favoriteTemplates",
JSON.stringify(favoriteTemplates)
)
} else {
const newFavoriteTemplates = favoriteTemplates.filter(
(id) => id !== templateId
)
localStorage.setItem(
"favoriteTemplates",
JSON.stringify(newFavoriteTemplates)
)
}
}

function getSortedTemplatesByFavorite() {
return template.sort((a, b) =>
isFavoriteTemplate(getTemplateId(a)) ===
isFavoriteTemplate(getTemplateId(b))
? 0
: isFavoriteTemplate(getTemplateId(a))
? -1
: 1
)
}

return (
<div className="grid min-h-screen w-full md:grid-cols-[220px_1fr] lg:grid-cols-[280px_1fr]">
<SelectTemplateSideBar
Expand All @@ -32,15 +81,17 @@ export default function IndexPage() {
</Link>
</div>


<div className="xl:flex xl:items-center xl:justify-center gap-6">
<h4 className="text-lg font-semibold mb-2 xl:mb-0">Page Type</h4>

<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{Object.keys(IPageType).map((page: string, index: number) => (
<Button
variant={`${pageType === (IPageType as any)[page] ? "default" : "outline"
}`}
variant={`${
pageType === (IPageType as any)[page]
? "default"
: "outline"
}`}
key={index}
onClick={() => setPageType((IPageType as any)[page])}
>
Expand All @@ -51,7 +102,6 @@ export default function IndexPage() {
</div>
</div>


{template.length === 0 && (
<div className="flex items-center justify-center size-full">
<div className="py-3 text-center">
Expand All @@ -62,13 +112,22 @@ export default function IndexPage() {

{template.length !== 0 && (
<div className="grid grid-cols-1 sm:grid-cols-2 gap-y-6 sm:gap-6 lg:grid-cols-3">
{template.map((template: ITemplate, index: number) => (
<Card {...template} key={index} />
))}
{getSortedTemplatesByFavorite().map(
(template: ITemplate, index: number) => (
<Card
{...template}
key={index}
isFavoriteTemplate={isFavoriteTemplate(
getTemplateId(template)
)}
toggleFavoriteTemplate={toggleFavoriteTemplate}
/>
)
)}
</div>
)}
</main>
</div >
</div >
</div>
</div>
)
}
21 changes: 19 additions & 2 deletions frontend/components/SelectTemplate/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import CardDescriptions from "./CardDescriptions"
import CardHeader from "./CardHeader"
import CardTags from "./CardTags"

export const Card: React.FC<Omit<ITemplate, "functions" | "image">> = ({
export const Card: React.FC<
Omit<ITemplate, "functions" | "image"> & {
isFavoriteTemplate: boolean
toggleFavoriteTemplate: (template: string) => void
}
> = ({
title,
author,
contributors,
Expand All @@ -23,10 +28,22 @@ export const Card: React.FC<Omit<ITemplate, "functions" | "image">> = ({
folder,
lastUpdated,
tags,
isFavoriteTemplate,
toggleFavoriteTemplate,
}) => {
function handleFavoriteTemplate() {
toggleFavoriteTemplate(title + dateCreated)
}

return (
<UICard className="bg-card/35">
<CardHeader title={title} author={author} featured={featured} />
<CardHeader
title={title}
author={author}
featured={featured}
isFavoriteTemplate={isFavoriteTemplate}
handleFavoriteTemplate={handleFavoriteTemplate}
/>
<CardContent>
<CardDescriptions description={description} />
<CardTags tags={tags} />
Expand Down
36 changes: 29 additions & 7 deletions frontend/components/SelectTemplate/Card/CardHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useState } from "react"
import { ITemplate } from "@/api/generated"
import { StarIcon } from "lucide-react"
import { Heart, StarIcon } from "lucide-react"

import { Badge } from "@/components/ui/badge"
import {
Expand All @@ -10,14 +11,35 @@ import {
import SocialButton from "@/components/common/SocialButton"

const CardHeader: React.FC<
Pick<ITemplate, "featured" | "title" | "author">
> = ({ featured, title, author }) => {
Pick<ITemplate, "featured" | "title" | "author"> & {
isFavoriteTemplate: boolean
handleFavoriteTemplate: () => void
}
> = ({
featured,
title,
author,
isFavoriteTemplate,
handleFavoriteTemplate,
}) => {
const [isFavorite, setIsFavorite] = useState(isFavoriteTemplate)
return (
<UICardHeader>
<div className="xl:flex xl:items-start xl:justify-between">
<CardTitle className={`${featured && "pb-2 xl:pb-0"}`}>
{title}
</CardTitle>
<div>
<div className="flex justify-between">
<CardTitle className={`flex-1 ${featured && "pb-2"}`}>
{title}
</CardTitle>
<Heart
className={`size-5 hover:cursor-pointer ${
isFavorite ? "fill-red-500" : "hover:animate-pulse"
}`}
onClick={() => {
handleFavoriteTemplate()
setIsFavorite(!isFavorite)
}}
/>
</div>
{featured && (
<Badge>
<div className="flex items-center justify-center">
Expand Down