tailwind+react组件实现销售后台仪表盘效果代码
代码语言:html
所属分类:布局界面
代码描述:tailwind+react组件实现销售后台仪表盘效果代码
代码标签: tailwind react 组件 销售 后台 仪表盘
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" /> <style> .half-circle-pie { display: block; width: 100%; max-width: 30rem; height: auto; } .icon { display: block; width: 1em; height: 1em; } </style> </head> <body class="bg-gray-200 text-black dark:bg-gray-900 dark:text-white transition-colors duration-300"> <div id="root"></div> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/babel.7.18.13.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/react.production.18.2.0.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/react-dom.production.18.2.0.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/tailwindcss.3.4.16.js"></script> <script type="text/babel"> const { useEffect, useRef, useState,StrictMode} = window.React; const { createRoot } = window.ReactDOM; class Formatter { static LOCALE = "en-US"; static CURRENCY = "USD"; static count(value) { return new Intl.NumberFormat(this.LOCALE).format(value); } static currency(value) { return new Intl.NumberFormat(this.LOCALE, { currency: this.CURRENCY, style: "currency", notation: "compact", maximumFractionDigits: 1 }).format(value); } static percent(value) { return new Intl.NumberFormat(this.LOCALE, { maximumFractionDigits: 1, style: "percent" }).format(value); } static date(date) { return new Intl.DateTimeFormat(this.LOCALE, { dateStyle: "short" }).format(date); } } class Random { static random() { return crypto.getRandomValues(new Uint32Array(1))[0] / 2**32; } static float(min, max) { return (this.random() * (max - min)) + min; } static hash() { return Math.round(this.float(0,1) * 0xffff).toString(16); } static int(min, max) { return Math.floor(this.random() * (max - min)) + min; } } function fakeData() { const data = { overview: { top: Random.int(1,15) / 100, sales_goals: 0.672, number_of_sales: 2608, change: 0.035, total_sales: 42200, total_change: -0.045 }, users: [ { name: "Jack O. Lantern", avatar: "https://assets.codepen.io/416221/photo-avatar1.jpg" }, { name: "Jane Doe", avatar: "https://assets.codepen.io/416221/photo-avatar2.jpg" }, { name: "Joe Schmoe", avatar: "https://assets.codepen.io/416221/photo-avatar3.jpg" } ], performance: { history: [] }, convert_rate: 0.375, customer_calls: [ { name: "Ann Thrax", vip: true, source: "TikTok Leads" } ], sales_target: { target: 42200, streams: [ { change: -0.2, revenue: 6800, source: "Instagram" }, { change: -0.45, revenue: 8200, source: "Facebook" }, { change: 0.7, revenue: 15400, source: "TikTok" }, { change: -0.5, revenue: 11800, source: "Other" } ] } }; const historyPercents = [0.8,0.2,0.5,0.2,0.9,0.3,0.55,0.3,0.15,0.8,0.35,0.3,0.4,0.2,0.85,0.25,0.852]; historyPercents.forEach((percent, i) => { const date = new Date(); date.setDate(date.getDate() - (historyPercents.length - (i + 1))); data.performance.history.push({date, percent}); }); return data; } createRoot(document.getElementById("root")).render( <StrictMode> <IconSprites /> <Dashboard data={fakeData()} /> </StrictMode> ); function ActionBar({ users }) { const newestUsers = users.slice(0,3); return ( <div className="flex flex-col sm:flex-row justify-between gap-x-1 gap-y-3 mb-6"> <div className="flex gap-1 items-center"> {newestUsers.map((user, i) => ( <Avatar key={i} {...user} indentStart={i > 0} /> ))} <Button color="black" icon="plus">Invite</Button> </div> <div className="flex gap-1 items-center"> <Button icon="calendar" shape="square" title="Calendar" /> <div className="sm:hidden"> <Button icon="arrow-down" shape="square" title="Download Report" /> </div> <div className="hidden sm:block"> <Button icon="arrow-down">Download Report</Button> </div> <div className="sm:hidden"> <Button color="red" icon="microphone" shape="square" title="AI Assistant" /> </div> <div className="hidden sm:block"> <Button color="red" icon="microphone">AI Assistant</Button> </div> </div> </div> ); } function Avatar({ name, avatar, indentStart }) { return ( <div className={`bg-gray-400 dark:bg-gray-700 border border-white dark:border-gray-800 rounded-full overflow-hidden w-12 h-12${indentStart ? ' -ms-8' : ''} transition-colors duration-300`}> <img className="block w-full h-auto" src={avatar} width="40" height="40" alt={name} title={name} /> </div> ); } function Button({ children, title, color, icon, shape = "regular", outline, clickEvent }) { const buttonFills = { default: "bg-white hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 ", outline: "hover:bg-gray-100 dark:hover:bg-gray-700 ", black: "bg-black hover:bg-gray-900 dark:bg-white dark:hover:bg-gray-100 ", red: "bg-red-600 hover:bg-red-700 " }; const buttonTexts = { default: "text-black dark:text-white ", black: "text-white dark:text-black ", white: "text-white ", red: "text-red-600 hover:text-red-700 dark:hover:text-red-500 " }; const buttonOutlines = { default: "border-2 border-gray-200 hover:border-gray-300 dark:border-gray-600 dark:hover:border-gray-500 ", red: "border-2 border-red-600 hover:border-red-700 dark:hover:border-red-500 " }; const buttonShapes = { regular: "px-5 py-3 min-w-12 ", square: "flex-shrink-0 w-12 ", wide: "py-3 w-full " }; let buttonFill = buttonFills["default"]; let buttonText = buttonTexts["default"]; let buttonOutline = ""; const buttonShape = buttonShapes[shape]; if (color === "black") { buttonFill = buttonFills[color]; buttonText = buttonTexts[color]; } else if (color && outline) { buttonFill = buttonFills["outline"]; buttonText = buttonTexts[color]; buttonOutline = buttonOutlines[color]; } else if (color) { buttonFill = buttonFills[color]; buttonText = buttonTexts["white"]; } else if (outline) { buttonOutline = buttonOutlines["default"]; } return ( <button className={`${buttonFill}${buttonText}${buttonOutline}focus:outline-none focus-visible:ring rounded-full font-light flex justify-center items-center gap-2 ${buttonShape}h-12 transition-colors duration-300`} type="button" title={title} onClick={() => clickEvent?.()}> {icon ? <Icon icon={icon} /> : ""} {children} </button> ); } function ConvertRate({ percent }) { const circumference = 34.56; const offset = 34.56 * (1 - percent); const dots = 16; const dotAngle = +(360 / dots).toFixed(2); const angles = []; for (let d = 0; d < dots; ++d) { angles.push(dotAngle * d); } return ( <div className="col-span-6 sm:col-span-2 lg:col-span-2 lg:row-span-2"> <div className="bg-black dark:bg-white aspect-square rounded-full text-white dark:text-black relative m-auto max-h-64 sm:max-h-none transition-colors duration-300"> <svg className="m-auto w-full h-auto rtl:-scale-x-100" viewBox="0 0 16 16" width="160px" height="160px" role="img" aria-label={`Ring chart showing a ${Formatter.percent(percent)} fill over a circle made of 16 dots`}> <g fill="currentcolor" transform="translate(8,8)".........完整代码请登录后点击上方下载按钮下载查看
网友评论0