-
-
Save shricodev/a5b5ad79ecfca26bf119e59c0b5bc95f to your computer and use it in GitHub Desktop.
Figma MCP Implementation - Gemini 2.5 Pro - Blog Demo
This file contains hidden or 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
| "use client"; | |
| export default function ExpenseChart() { | |
| // Chart data representing different heights for each bar | |
| const chartData = [ | |
| 35, 52, 44, 35, 30, 44, 27, 27, 35, 52, 44, 35, 30, 44, 27, 27, 35, 52, 44, 35, 60, 44, 27 | |
| ]; | |
| return ( | |
| <div className="h-[60px] flex items-end gap-[6px]"> | |
| {chartData.map((height, index) => ( | |
| <div | |
| key={index} | |
| className="w-[16px] bg-[#157AFF] rounded-sm transition-all hover:opacity-80" | |
| style={{ | |
| height: `${height}px`, | |
| opacity: index === 20 ? 1 : 0.2, // Highlight the 21st bar | |
| }} | |
| /> | |
| ))} | |
| </div> | |
| ); | |
| } |
This file contains hidden or 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
| "use client"; | |
| interface ExpenseItemProps { | |
| expense: { | |
| id: number; | |
| category: string; | |
| description: string; | |
| time: string; | |
| amount: number; | |
| color: string; | |
| icon: string; | |
| }; | |
| } | |
| export default function ExpenseItem({ expense }: ExpenseItemProps) { | |
| const formatAmount = (amount: number) => { | |
| return amount.toLocaleString('id-ID').replace(/,/g, '.'); | |
| }; | |
| const getIcon = (type: string) => { | |
| switch (type) { | |
| case "grocery": | |
| return ( | |
| <svg width="16" height="16" viewBox="0 0 16 16" fill="none"> | |
| <path d="M3.19 3.2L13.01 3.2" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/> | |
| <path d="M3.19 12L13.01 12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/> | |
| <path d="M13.01 3.2V12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/> | |
| </svg> | |
| ); | |
| case "transport": | |
| return ( | |
| <svg width="14" height="16" viewBox="0 0 14 16" fill="none"> | |
| <path d="M0 0H13.47V16L6.735 12.21L0 16V0Z" fill="currentColor"/> | |
| <circle cx="2.53" cy="2.53" r="1.265" fill="white"/> | |
| <circle cx="6.735" cy="2.53" r="1.265" fill="white"/> | |
| <circle cx="10.94" cy="2.53" r="1.265" fill="white"/> | |
| <rect x="2.53" y="6.32" width="7.58" height="4.21" fill="white"/> | |
| </svg> | |
| ); | |
| case "housing": | |
| return ( | |
| <svg width="16" height="14" viewBox="0 0 16 14" fill="none"> | |
| <path d="M0 6L8 0L16 6V13.6H0V6Z" fill="currentColor"/> | |
| </svg> | |
| ); | |
| case "food": | |
| return ( | |
| <svg width="18" height="11" viewBox="0 0 18 11" fill="none"> | |
| <path d="M0 0H17.83V11H0V0Z" fill="currentColor"/> | |
| <rect x="14.75" y="1.71" width="3.08" height="1.71" fill="white"/> | |
| <rect x="14.89" y="5.4" width="2.94" height="5.4" fill="white"/> | |
| </svg> | |
| ); | |
| case "entertainment": | |
| return ( | |
| <svg width="18" height="18" viewBox="0 0 18 18" fill="none"> | |
| <circle cx="9" cy="9" r="9" fill="currentColor"/> | |
| <path d="M7 6V12L12.4 9L7 6Z" fill="white"/> | |
| </svg> | |
| ); | |
| default: | |
| return null; | |
| } | |
| }; | |
| return ( | |
| <div className="flex items-center justify-between"> | |
| <div className="flex items-center gap-4"> | |
| {/* Icon */} | |
| <div | |
| className="w-12 h-12 rounded-full flex items-center justify-center" | |
| style={{ backgroundColor: expense.color }} | |
| > | |
| <div className="text-white opacity-70"> | |
| {getIcon(expense.icon)} | |
| </div> | |
| </div> | |
| {/* Details */} | |
| <div> | |
| <h4 className="text-[16px] font-medium text-[#273240]">{expense.category}</h4> | |
| <p className="text-[14px] text-[#404852] opacity-50"> | |
| {expense.time} • {expense.description} | |
| </p> | |
| </div> | |
| </div> | |
| {/* Amount */} | |
| <span className="text-[16px] font-semibold text-[#273240]"> | |
| {formatAmount(expense.amount)} | |
| </span> | |
| </div> | |
| ); | |
| } |
This file contains hidden or 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
| @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap'); | |
| @tailwind base; | |
| @tailwind components; | |
| @tailwind utilities; | |
| :root { | |
| --background: #101010; | |
| --foreground: #ffffff; | |
| --primary: #157AFF; | |
| --secondary: #273240; | |
| --accent: #31BA96; | |
| --muted: #404852; | |
| --card: #F9FAFC; | |
| --border: #D2DCE8; | |
| } | |
| * { | |
| box-sizing: border-box; | |
| padding: 0; | |
| margin: 0; | |
| } | |
| html, | |
| body { | |
| max-width: 100vw; | |
| overflow-x: hidden; | |
| font-family: 'Poppins', sans-serif; | |
| } | |
| body { | |
| color: var(--foreground); | |
| background: var(--background); | |
| } | |
| a { | |
| color: inherit; | |
| text-decoration: none; | |
| } | |
| /* Custom scrollbar */ | |
| ::-webkit-scrollbar { | |
| width: 8px; | |
| height: 8px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: rgba(255, 255, 255, 0.1); | |
| border-radius: 4px; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: rgba(255, 255, 255, 0.3); | |
| border-radius: 4px; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: rgba(255, 255, 255, 0.5); | |
| } |
This file contains hidden or 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
| import type { Metadata } from "next"; | |
| import "./globals.css"; | |
| export const metadata: Metadata = { | |
| title: "Dashboard - Expenses Tracker", | |
| description: "Track your expenses and manage your finances", | |
| }; | |
| export default function RootLayout({ | |
| children, | |
| }: Readonly<{ | |
| children: React.ReactNode; | |
| }>) { | |
| return ( | |
| <html lang="en"> | |
| <body>{children}</body> | |
| </html> | |
| ); | |
| } |
This file contains hidden or 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
| "use client"; | |
| import Image from "next/image"; | |
| import ExpenseChart from "./ExpenseChart"; | |
| import ExpenseItem from "./ExpenseItem"; | |
| export default function MainContent() { | |
| const expenses = [ | |
| { | |
| id: 1, | |
| category: "Grocery", | |
| description: "Belanja di pasar", | |
| time: "5:12 pm", | |
| amount: -326800, | |
| color: "#32A7E2", | |
| icon: "grocery", | |
| }, | |
| { | |
| id: 2, | |
| category: "Transportation", | |
| description: "Naik bus umum", | |
| time: "5:12 pm", | |
| amount: -15000, | |
| color: "#B548C6", | |
| icon: "transport", | |
| }, | |
| { | |
| id: 3, | |
| category: "Housing", | |
| description: "Bayar Listrik", | |
| time: "5:12 pm", | |
| amount: -185750, | |
| color: "#FF8700", | |
| icon: "housing", | |
| }, | |
| { | |
| id: 4, | |
| category: "Food and Drink", | |
| description: "Makan Steak", | |
| time: "5:12 pm", | |
| amount: -156000, | |
| color: "#DC3434", | |
| icon: "food", | |
| }, | |
| { | |
| id: 5, | |
| category: "Entertainment", | |
| description: "Nonton Bioskop", | |
| time: "5:12 pm", | |
| amount: -35200, | |
| color: "#4BA83D", | |
| icon: "entertainment", | |
| }, | |
| ]; | |
| return ( | |
| <div className="flex-1 px-[100px] py-[60px] overflow-y-auto"> | |
| {/* Header */} | |
| <div className="mb-12"> | |
| <div className="flex items-center justify-between mb-2"> | |
| <h1 className="text-[40px] font-semibold text-[#262A41]">Expenses</h1> | |
| <div className="flex items-center gap-6"> | |
| {/* User Avatars */} | |
| <div className="flex -space-x-3"> | |
| <div className="w-8 h-8 rounded-full border-2 border-white overflow-hidden"> | |
| <Image | |
| src="/images/user3.png" | |
| alt="User" | |
| width={32} | |
| height={32} | |
| className="w-full h-full object-cover" | |
| /> | |
| </div> | |
| <div className="w-8 h-8 rounded-full border-2 border-white overflow-hidden"> | |
| <Image | |
| src="/images/user2.png" | |
| alt="User" | |
| width={32} | |
| height={32} | |
| className="w-full h-full object-cover" | |
| /> | |
| </div> | |
| <div className="w-8 h-8 rounded-full border-2 border-white overflow-hidden"> | |
| <Image | |
| src="/images/user1.png" | |
| alt="User" | |
| width={32} | |
| height={32} | |
| className="w-full h-full object-cover" | |
| /> | |
| </div> | |
| <button className="w-8 h-8 rounded-full border-2 border-[#D2DCE8] bg-white flex items-center justify-center"> | |
| <svg width="9" height="9" viewBox="0 0 9 9" fill="none"> | |
| <path d="M4.5 0V9" stroke="#D8D8D8" strokeWidth="2"/> | |
| <path d="M0 4.5H9" stroke="#D8D8D8" strokeWidth="2"/> | |
| </svg> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <p className="text-[16px] text-[#101010] opacity-50">01 - 25 March, 2020</p> | |
| </div> | |
| {/* Expense Chart */} | |
| <ExpenseChart /> | |
| {/* Date Section - Today */} | |
| <div className="mt-12 mb-6"> | |
| <div className="flex items-center justify-between"> | |
| <h3 className="text-[18px] text-[#262A41]">Today</h3> | |
| <div className="flex items-center gap-2"> | |
| <div className="flex gap-[5px]"> | |
| <div className="w-[5px] h-[5px] bg-[#D8D8D8] rounded-full"></div> | |
| <div className="w-[5px] h-[5px] bg-[#D8D8D8] rounded-full"></div> | |
| <div className="w-[5px] h-[5px] bg-[#D8D8D8] rounded-full"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <div className="w-full h-[0.5px] bg-[#DEDEDE] mt-3"></div> | |
| </div> | |
| {/* Expense Items */} | |
| <div className="space-y-6"> | |
| {expenses.slice(0, 3).map((expense) => ( | |
| <ExpenseItem key={expense.id} expense={expense} /> | |
| ))} | |
| </div> | |
| {/* Date Section - Monday */} | |
| <div className="mt-12 mb-6"> | |
| <div className="flex items-center justify-between"> | |
| <h3 className="text-[18px] text-[#262A41]">Monday, 23 March 2020</h3> | |
| <div className="flex items-center gap-2"> | |
| <div className="flex gap-[5px]"> | |
| <div className="w-[5px] h-[5px] bg-[#D8D8D8] rounded-full"></div> | |
| <div className="w-[5px] h-[5px] bg-[#D8D8D8] rounded-full"></div> | |
| <div className="w-[5px] h-[5px] bg-[#D8D8D8] rounded-full"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <div className="w-full h-[0.5px] bg-[#DEDEDE] mt-3"></div> | |
| </div> | |
| {/* More Expense Items */} | |
| <div className="space-y-6"> | |
| {expenses.slice(3).map((expense) => ( | |
| <ExpenseItem key={expense.id} expense={expense} /> | |
| ))} | |
| </div> | |
| </div> | |
| ); | |
| } |
This file contains hidden or 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
| "use client"; | |
| import { useState } from "react"; | |
| import Sidebar from "./components/Sidebar"; | |
| import MainContent from "./components/MainContent"; | |
| import RightPanel from "./components/RightPanel"; | |
| export default function Dashboard() { | |
| const [activeMenu, setActiveMenu] = useState("expenses"); | |
| return ( | |
| <div className="flex h-screen bg-black overflow-hidden"> | |
| {/* Main Container with rounded corners */} | |
| <div className="flex w-full h-full p-5"> | |
| <div className="flex w-full bg-white rounded-[30px] overflow-hidden"> | |
| {/* Sidebar */} | |
| <Sidebar activeMenu={activeMenu} setActiveMenu={setActiveMenu} /> | |
| {/* Main Content Area */} | |
| <MainContent /> | |
| {/* Right Panel */} | |
| <RightPanel /> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } |
This file contains hidden or 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
| "use client"; | |
| import Image from "next/image"; | |
| export default function RightPanel() { | |
| const stats = [ | |
| { category: "Food and Drinks", amount: "872.400", percentage: 28, color: "#31BA96" }, | |
| { category: "Shopping", amount: "1.378.200", percentage: 44, color: "#31BA96" }, | |
| { category: "Housing", amount: "928.500", percentage: 36, color: "#31BA96" }, | |
| { category: "Transportation", amount: "420.700", percentage: 24, color: "#31BA96" }, | |
| { category: "Vehicle", amount: "520.000", percentage: 36, color: "#31BA96" }, | |
| ]; | |
| return ( | |
| <div className="w-[350px] bg-[#F9FAFC] p-[50px] overflow-y-auto"> | |
| {/* Stats Section */} | |
| <div className="mb-16"> | |
| <h2 className="text-[20px] text-[#262A41] mb-8">Where your money go?</h2> | |
| <div className="space-y-8"> | |
| {stats.map((stat, index) => ( | |
| <div key={index}> | |
| <div className="flex justify-between items-center mb-2"> | |
| <span className="text-[13px] font-medium text-[#273240]"> | |
| {stat.category} | |
| </span> | |
| <span className="text-[13px] text-[#273240]">{stat.amount}</span> | |
| </div> | |
| <div className="relative h-[5px] bg-[#ECEFF5] rounded-[5px]"> | |
| <div | |
| className="absolute top-0 left-0 h-full rounded-[5px]" | |
| style={{ | |
| width: `${stat.percentage}%`, | |
| backgroundColor: stat.color, | |
| }} | |
| /> | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| {/* Save More Money Section */} | |
| <div className="relative"> | |
| {/* Background Card */} | |
| <div className="bg-[#EDF0F6] rounded-[15px] p-6 pt-[120px]"> | |
| {/* Illustration */} | |
| <div className="absolute top-0 right-6 w-[84px] h-[72px]"> | |
| {/* Shopping Bags Illustration */} | |
| <div className="relative"> | |
| {/* Orange Bag */} | |
| <div className="absolute bottom-0 left-0 w-[84px] h-[42px] bg-gradient-to-br from-[#FFB966] to-[#FF895F] rounded-sm"> | |
| <div className="absolute top-[17px] left-[44px] w-[20px] h-[2px] bg-white/30"></div> | |
| <div className="absolute -top-[8px] right-[30px] w-[16px] h-[16px] rounded-full bg-[#E0987C]"></div> | |
| <div className="absolute bottom-[8px] w-full h-[1px] bg-[#D33234]"></div> | |
| </div> | |
| {/* Blue Bag */} | |
| <div className="absolute bottom-[30px] right-0 w-[61px] h-[30px] bg-gradient-to-br from-[#85D4FF] to-[#51A4FF] rounded-sm"> | |
| <div className="absolute top-[15px] left-[32px] w-[16px] h-[0.65px] bg-[#0069D5]"></div> | |
| <div className="absolute bottom-[6px] w-full h-[1px] bg-[#0069D5]"></div> | |
| </div> | |
| </div> | |
| {/* Coins */} | |
| <div className="absolute -top-2 left-0"> | |
| <div className="flex gap-2"> | |
| <div className="w-[26px] h-[73px] relative"> | |
| <div className="absolute bottom-0 w-[25px] h-[34px] bg-[#C5DDF0] rounded-full"></div> | |
| <div className="absolute bottom-[8px] left-[3px] w-[15px] h-[64px] bg-[#7297C4]"></div> | |
| </div> | |
| <div className="w-[27px] h-[50px] relative"> | |
| <div className="absolute bottom-0 w-[26px] h-[31px] bg-[#C5DDF0] rounded-full"></div> | |
| <div className="absolute bottom-[10px] left-[9px] w-[14px] h-[40px] bg-[#7297C4]"></div> | |
| </div> | |
| <div className="w-[22px] h-[36px] relative"> | |
| <div className="absolute bottom-0 w-[21px] h-[23px] bg-[#C5DDF0] rounded-full"></div> | |
| <div className="absolute bottom-[6px] left-[1px] w-[15px] h-[29px] bg-[#7297C4]"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <h3 className="text-[16px] font-semibold text-[#273240] mb-2"> | |
| Save more money | |
| </h3> | |
| <p className="text-[12px] text-[#404852] opacity-70 leading-[21px] mb-6"> | |
| eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim. | |
| </p> | |
| {/* View Tips Button */} | |
| <button className="w-full h-[45px] bg-[#101010] text-white rounded-[8px] font-semibold text-[13px] tracking-[0.15em] hover:bg-gray-900 transition-colors"> | |
| VIEW TIPS | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment