Skip to content

Commit

Permalink
refactor: refactoring the code
Browse files Browse the repository at this point in the history
  • Loading branch information
vwh committed Sep 25, 2024
1 parent 798d6d5 commit 80f8cba
Show file tree
Hide file tree
Showing 7 changed files with 372 additions and 378 deletions.
80 changes: 46 additions & 34 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,59 @@
import { useMemo } from "react";
import { useStore } from "@/store/useStore";
import type { Icons } from "@/types";

import { cn } from "@/lib/utils";
import * as svgs from "lucide-react";

import Navbar from "@/components/navbar";
import Sidebar from "@/components/sidebar";
import DotPattern from "@/components/magicui/dot-pattern";
import * as svgs from "lucide-react";

export default function App() {
const App: React.FC = () => {
const { svgSettings, selectedSvgName } = useStore();
const SvgComponent = svgs[selectedSvgName as Icons];

const containerStyle = useMemo(
() => ({
width: "256px",
height: "256px",
borderRadius: `${svgSettings.radius}px`,
backgroundColor: svgSettings.bgColor,
position: "relative" as const,
overflow: "hidden",
boxShadow: `${svgSettings.shadowOffsetX}px ${svgSettings.shadowOffsetY}px ${svgSettings.shadowBlur}px ${svgSettings.shadowColor}`,
filter: `blur(${svgSettings.backgroundBlur}px)`
}),
[svgSettings]
);

const svgWrapperStyle = useMemo(
() => ({
position: "absolute" as const,
top: `${128 + svgSettings.position.y - svgSettings.size / 2}px`,
left: `${128 + svgSettings.position.x - svgSettings.size / 2}px`,
transform: `skew(${svgSettings.skewX}deg, ${svgSettings.skewY}deg)`,
opacity: svgSettings.opacity,
filter: `blur(${svgSettings.iconBlur}px)`
}),
[svgSettings]
);

const svgStyle = useMemo(
() => ({
position: "absolute" as const,
transform: `rotate(${svgSettings.rotation}deg) scale(${svgSettings.scale})`
}),
[svgSettings]
);

return (
<>
<Navbar />
<main className="flex h-[calc(100vh-68px)] flex-col md:flex-row">
<main className="flex flex-col md:h-[calc(100vh-68px)] md:flex-row">
<Sidebar />
<section className="relative flex h-full w-full items-center justify-center overflow-hidden bg-background md:shadow-xl">
<div
className="z-50"
id="svg-container"
style={{
width: "256px",
height: "256px",
borderRadius: `${svgSettings.radius}px`,
backgroundColor: svgSettings.bgColor,
position: "relative",
overflow: "hidden",
boxShadow: `${svgSettings.shadowOffsetX}px ${svgSettings.shadowOffsetY}px ${svgSettings.shadowBlur}px ${svgSettings.shadowColor}`,
filter: `blur(${svgSettings.backgroundBlur}px)`
}}
>
<div
style={{
position: "absolute",
top: `${128 + svgSettings.position.y - svgSettings.size / 2}px`,
left: `${128 + svgSettings.position.x - svgSettings.size / 2}px`,
transform: `skew(${svgSettings.skewX}deg, ${svgSettings.skewY}deg)`,
opacity: svgSettings.opacity,
filter: `blur(${svgSettings.iconBlur}px)`
}}
>
<section className="relative flex h-[300px] w-full flex-grow items-center justify-center overflow-hidden bg-background md:h-full md:shadow-xl">
<div className="z-50" id="svg-container" style={containerStyle}>
<div style={svgWrapperStyle}>
<SvgComponent
fill={svgSettings.fillColor}
fillOpacity={svgSettings.fillOpacity}
Expand All @@ -50,10 +63,7 @@ export default function App() {
strokeLinejoin="round"
width={svgSettings.size}
height={svgSettings.size}
style={{
position: "absolute",
transform: `rotate(${svgSettings.rotation}deg) scale(${svgSettings.scale})`
}}
style={svgStyle}
/>
</div>
</div>
Expand All @@ -66,4 +76,6 @@ export default function App() {
</main>
</>
);
}
};

export default App;
100 changes: 37 additions & 63 deletions src/components/icons-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@ import React, { useMemo, useState, useCallback } from "react";
import { useStore } from "@/store/useStore";
import type { Icons } from "@/types";

import {
Dialog,
DialogContent,
DialogTrigger,
DialogClose
} from "@/components/ui/dialog";
import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import * as svgs from "lucide-react";
Expand All @@ -27,25 +22,25 @@ export default function IconsDialog() {
);
}, [searchTerm]);

const iconButtons = useMemo(() => {
const { iconButtons, totalPages } = useMemo(() => {
const totalPages = Math.ceil(filteredIconNames.length / ICONS_PER_PAGE);
return {
buttons: filteredIconNames
.slice(currentPage * ICONS_PER_PAGE, (currentPage + 1) * ICONS_PER_PAGE)
.map((name) => {
const IconComponent = svgs[name as Icons];
return (
<MemoizedIconButton
key={name}
name={name}
icon={IconComponent}
onClick={() => setSelectedSvgName(name as Icons)}
/>
);
}),
totalPages
};
}, [currentPage, setSelectedSvgName, filteredIconNames]);
const buttons = filteredIconNames
.slice(currentPage * ICONS_PER_PAGE, (currentPage + 1) * ICONS_PER_PAGE)
.map((name) => {
const SvgComponent = svgs[name as Icons];
return (
<Button
key={name}
onClick={() => setSelectedSvgName(name as Icons)}
className="flex h-14 w-14 items-center justify-center rounded-lg transition-all hover:opacity-80 md:h-16 md:w-16"
title={name}
>
<SvgComponent className="h-36 w-36" />
</Button>
);
});
return { iconButtons: buttons, totalPages };
}, [currentPage, setSelectedSvgName, filteredIconNames, selectedSvgName]);

const handleSearch = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -58,67 +53,46 @@ export default function IconsDialog() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="gooeyRight" className="w-full">
<Button className="flex h-12 w-full items-center justify-center gap-2">
<SvgComponent />
<span>Select Icon</span>
</Button>
</DialogTrigger>
<DialogContent>
<section className="flex flex-col gap-3 text-center">
<DialogContent className="sm:max-w-[425px]">
<div className="flex flex-col gap-4">
<Input
type="text"
placeholder="Search"
className="border-[3px]"
placeholder="Search Icons..."
value={searchTerm}
onChange={handleSearch}
className="w-full"
/>
<div className="grid grid-cols-5 gap-2">{iconButtons.buttons}</div>
<div className="flex justify-center gap-2 border-t-2 pt-3">
<div className="flex flex-wrap items-center justify-center gap-1 p-2">
{iconButtons}
</div>
<div className="flex items-center justify-between">
<Button
className="w-full"
onClick={() => setCurrentPage((prev) => Math.max(0, prev - 1))}
disabled={currentPage === 0}
variant="outline"
>
<svgs.ChevronLeft />
</Button>
{/* <span className="self-center">
Page {currentPage + 1} of {iconButtons.totalPages}
</span> */}
<span>
Page {currentPage + 1} of {totalPages}
</span>
<Button
className="w-full"
onClick={() =>
setCurrentPage((prev) =>
Math.min(iconButtons.totalPages - 1, prev + 1)
)
setCurrentPage((prev) => Math.min(totalPages - 1, prev + 1))
}
disabled={currentPage === iconButtons.totalPages - 1}
disabled={currentPage === totalPages - 1}
variant="outline"
>
<svgs.ChevronRight />
</Button>
</div>
</section>
</div>
</DialogContent>
</Dialog>
);
}

const MemoizedIconButton = React.memo(
({
name,
icon: Icon,
onClick
}: {
name: string;
icon: React.ElementType;
onClick: () => void;
}) => (
<DialogClose>
<Button
onClick={onClick}
className="flex w-full items-center justify-center gap-2"
title={name}
>
<Icon size={24} />
</Button>
</DialogClose>
)
);
Loading

0 comments on commit 80f8cba

Please sign in to comment.