| import React, { useState, useEffect } from 'react'; |
| import { motion } from 'framer-motion'; |
|
|
| const FinancialOpsAdmin = ({ onBack }) => { |
| const [profitData, setProfitData] = useState(null); |
|
|
| useEffect(() => { |
| fetch('http://localhost:8000/api/v1/profitability/store_01') |
| .then(res => res.json()) |
| .then(data => setProfitData(data)) |
| .catch(err => console.error(err)); |
| }, []); |
|
|
| return ( |
| <> |
| |
| {/* BEGIN: Sidebar */} |
| <nav aria-label="Sidebar" className="w-64 flex-shrink-0 border-r border-obsidian-border bg-obsidian-bg flex flex-col justify-between"> |
| <div> |
| {/* Brand */} |
| <div className="h-16 flex items-center px-6 border-b border-obsidian-border"> |
| <svg className="w-6 h-6 text-obsidian-text mr-2" fill="none" stroke="currentColor" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M13 10V3L4 14h7v7l9-11h-7z" strokeLinecap="square" strokeLinejoin="miter" strokeWidth="2"></path></svg> |
| <span className="font-semibold tracking-wide text-sm uppercase">HyperFlow</span> |
| </div> |
| {/* Navigation Links */} |
| <div className="p-4 space-y-1"> |
| <a className="flex items-center px-3 py-2 text-sm font-medium bg-obsidian-border text-obsidian-text border border-obsidian-border cursor-pointer" onClick={onBack} href="#"> |
| <svg className="w-4 h-4 mr-3 text-obsidian-muted" fill="none" stroke="currentColor" viewbox="0 0 24 24"><path d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" strokeLinecap="square" strokeLinejoin="miter" strokeWidth="2"></path></svg> |
| Dashboard |
| </a> |
| <a className="flex items-center px-3 py-2 text-sm font-medium text-obsidian-muted hover:text-obsidian-text hover:bg-[#151515] border border-transparent hover:border-obsidian-border transition-colors" href="#"> |
| <svg className="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewbox="0 0 24 24"><path d="M9 17h6M9 13h6m-6-4h6M4 6h16M4 10h16M4 14h16M4 18h16" strokeLinecap="square" strokeLinejoin="miter" strokeWidth="2"></path></svg> |
| Transactions |
| </a> |
| <a className="flex items-center px-3 py-2 text-sm font-medium text-obsidian-muted hover:text-obsidian-text hover:bg-[#151515] border border-transparent hover:border-obsidian-border transition-colors" href="#"> |
| <svg className="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewbox="0 0 24 24"><path d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" strokeLinecap="square" strokeLinejoin="miter" strokeWidth="2"></path></svg> |
| Payouts |
| </a> |
| </div> |
| </div> |
| {/* User Section */} |
| <div className="p-4 border-t border-obsidian-border"> |
| <div className="flex items-center"> |
| <img alt="Admin User" className="h-8 w-8 object-cover border border-obsidian-border" src="https://lh3.googleusercontent.com/aida/AP1WRLv9wlAZe2hhMPwWygVWbbf7ZRu67jUQ2SYDC7XN9GufD2BtBPvEMf3WXFWwhqMVaBlnqkAJgYR2cG5NeLSCIBeVFbTkc8ruPttElEVkmtWZaoCGBiq3UCuigAiK4nXfOhT1tdv5g95PrxWV_ng1VToHIMv62-SwHaVmaMGItM7Id_r-Rs-_XCd7B_r3t0cBCqpIwaRYUHcd2o7JFcSHssf0e2arDxLlwtYjUlUI-BTe2cXiyZj9WiMT21s"/> |
| <div className="ml-3"> |
| <p className="text-sm font-medium text-obsidian-text">SysAdmin</p> |
| <p className="text-xs text-obsidian-muted">Financial Ops</p> |
| </div> |
| </div> |
| </div> |
| </nav> |
| {/* END: Sidebar */} |
| {/* BEGIN: MainContent */} |
| <main className="flex-1 flex flex-col overflow-hidden bg-obsidian-bg"> |
| {/* BEGIN: Header */} |
| <header className="h-16 flex items-center justify-between px-8 border-b border-obsidian-border precision-panel"> |
| <h1 className="text-lg font-semibold text-obsidian-text">Financial Operations</h1> |
| <div className="flex items-center space-x-4"> |
| {/* Date Range Filter */} |
| <div className="flex items-center space-x-2 text-sm text-obsidian-muted border border-obsidian-border px-3 py-1.5 bg-obsidian-bg"> |
| <svg className="w-4 h-4" fill="none" stroke="currentColor" viewbox="0 0 24 24"><path d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" strokeLinecap="square" strokeLinejoin="miter" strokeWidth="2"></path></svg> |
| <span>Oct 1, 2023 - Oct 31, 2023</span> |
| </div> |
| {/* Action Button */} |
| <button className="precision-button px-4 py-1.5 text-sm font-medium text-obsidian-text flex items-center"> |
| <svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewbox="0 0 24 24"><path d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" strokeLinecap="square" strokeLinejoin="miter" strokeWidth="2"></path></svg> |
| Export CSV |
| </button> |
| </div> |
| </header> |
| {/* END: Header */} |
| <div className="flex-1 overflow-y-auto p-8"> |
| <div className="max-w-7xl mx-auto space-y-8"> |
| {/* BEGIN: FinancialOverview */} |
| <motion.section |
| initial={{ opacity: 0, y: 20 }} |
| animate={{ opacity: 1, y: 0 }} |
| transition={{ duration: 0.5 }} |
| aria-label="Financial Overview Cards" |
| className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4" |
| > |
| {/* Overview Card 1: Months to Profit */} |
| <article className="precision-panel p-5 flex flex-col justify-between"> |
| <h3 className="text-xs font-medium text-obsidian-muted uppercase tracking-wider mb-1">Time To Profitability</h3> |
| <div className="text-2xl font-semibold text-obsidian-text font-mono"> |
| {profitData ? `${profitData.profitability_projection.months_to_profit_median.toFixed(1)} mo` : "Loading..."} |
| </div> |
| <div className="mt-4 flex items-center text-xs text-obsidian-success"> |
| <svg className="w-3 h-3 mr-1" fill="none" stroke="currentColor" viewbox="0 0 24 24"><path d="M5 10l7-7m0 0l7 7m-7-7v18" strokeLinecap="square" strokeLinejoin="miter" strokeWidth="2"></path></svg> |
| <span>Cox PH Median Estimate</span> |
| </div> |
| </article> |
| {/* Overview Card 2: Density */} |
| <article className="precision-panel p-5 flex flex-col justify-between"> |
| <h3 className="text-xs font-medium text-obsidian-muted uppercase tracking-wider mb-1">Population Density</h3> |
| <div className="text-2xl font-semibold text-obsidian-text font-mono"> |
| {profitData ? profitData.metrics.population_density : "--"} |
| </div> |
| <div className="mt-4 flex items-center text-xs text-obsidian-muted"> |
| <span>Active users / sq km</span> |
| </div> |
| </article> |
| {/* Overview Card 3: Non-Grocery */} |
| <article className="precision-panel p-5 flex flex-col justify-between"> |
| <h3 className="text-xs font-medium text-obsidian-muted uppercase tracking-wider mb-1">Non-Grocery Share</h3> |
| <div className="text-2xl font-semibold text-obsidian-text font-mono"> |
| {profitData ? `${(profitData.metrics.non_grocery_share * 100).toFixed(0)}%` : "--"} |
| </div> |
| <div className="mt-4 flex items-center text-xs text-obsidian-success"> |
| <svg className="w-3 h-3 mr-1" fill="none" stroke="currentColor" viewbox="0 0 24 24"><path d="M5 10l7-7m0 0l7 7m-7-7v18" strokeLinecap="square" strokeLinejoin="miter" strokeWidth="2"></path></svg> |
| <span>High margin category</span> |
| </div> |
| </article> |
| {/* Overview Card 4: Recommendation */} |
| <article className="precision-panel p-5 flex flex-col justify-between"> |
| <h3 className="text-xs font-medium text-obsidian-muted uppercase tracking-wider mb-1">Allocation Strategy</h3> |
| <div className="text-sm font-semibold text-obsidian-text"> |
| {profitData ? profitData.profitability_projection.allocation_recommendation : "Loading..."} |
| </div> |
| <div className="mt-4 flex items-center text-xs text-obsidian-muted"> |
| <span>AI generated action plan</span> |
| </div> |
| </article> |
| </motion.section> |
| {/* END: FinancialOverview */} |
| {/* BEGIN: Main Content Grid */} |
| <div className="grid grid-cols-1 lg:grid-cols-3 gap-8"> |
| {/* BEGIN: Survival Curve Chart */} |
| <motion.section |
| initial={{ opacity: 0, scale: 0.95 }} |
| animate={{ opacity: 1, scale: 1 }} |
| transition={{ duration: 0.6, delay: 0.2 }} |
| aria-label="Cox PH Survival Curve" |
| className="precision-panel p-6" |
| > |
| <div className="flex items-center justify-between"> |
| <h2 className="text-sm font-semibold text-obsidian-text uppercase tracking-wide">Recent Transactions</h2> |
| <a className="text-xs text-obsidian-accent hover:text-obsidian-accentHover font-medium" href="#">View All →</a> |
| </div> |
| <div className="precision-panel overflow-hidden"> |
| <table className="min-w-full divide-y divide-obsidian-border"> |
| <thead className="bg-[#151515]"> |
| <tr> |
| <th className="px-4 py-3 text-left text-xs font-medium text-obsidian-muted uppercase tracking-wider" scope="col">Transaction ID</th> |
| <th className="px-4 py-3 text-left text-xs font-medium text-obsidian-muted uppercase tracking-wider" scope="col">Date & Time</th> |
| <th className="px-4 py-3 text-right text-xs font-medium text-obsidian-muted uppercase tracking-wider" scope="col">Amount</th> |
| <th className="px-4 py-3 text-left text-xs font-medium text-obsidian-muted uppercase tracking-wider" scope="col">Destination</th> |
| <th className="px-4 py-3 text-left text-xs font-medium text-obsidian-muted uppercase tracking-wider" scope="col">Status</th> |
| </tr> |
| </thead> |
| <tbody className="divide-y divide-obsidian-border bg-obsidian-surface"> |
| <tr> |
| <td className="px-4 py-3 whitespace-nowrap text-sm font-mono text-obsidian-text">TXN-0982-A</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm text-obsidian-muted">Oct 24, 14:32:01</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm font-mono text-right text-obsidian-text">$1,250.00</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm text-obsidian-text">Acme Corp</td> |
| <td className="px-4 py-3 whitespace-nowrap"> |
| <span className="inline-flex items-center px-2 py-0.5 border border-obsidian-success text-xs font-medium text-obsidian-success bg-transparent">Completed</span> |
| </td> |
| </tr> |
| <tr> |
| <td className="px-4 py-3 whitespace-nowrap text-sm font-mono text-obsidian-text">TXN-0981-B</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm text-obsidian-muted">Oct 24, 14:28:44</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm font-mono text-right text-obsidian-text">$8,400.00</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm text-obsidian-text">Stark Ind.</td> |
| <td className="px-4 py-3 whitespace-nowrap"> |
| <span className="inline-flex items-center px-2 py-0.5 border border-obsidian-warning text-xs font-medium text-obsidian-warning bg-transparent">Pending</span> |
| </td> |
| </tr> |
| <tr> |
| <td className="px-4 py-3 whitespace-nowrap text-sm font-mono text-obsidian-text">TXN-0980-C</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm text-obsidian-muted">Oct 24, 13:15:20</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm font-mono text-right text-obsidian-text">$345.50</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm text-obsidian-text">Wayne Ent.</td> |
| <td className="px-4 py-3 whitespace-nowrap"> |
| <span className="inline-flex items-center px-2 py-0.5 border border-obsidian-success text-xs font-medium text-obsidian-success bg-transparent">Completed</span> |
| </td> |
| </tr> |
| <tr> |
| <td className="px-4 py-3 whitespace-nowrap text-sm font-mono text-obsidian-text">TXN-0979-D</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm text-obsidian-muted">Oct 24, 11:05:12</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm font-mono text-right text-obsidian-text">$12,000.00</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm text-obsidian-text">LexCorp</td> |
| <td className="px-4 py-3 whitespace-nowrap"> |
| <span className="inline-flex items-center px-2 py-0.5 border border-obsidian-danger text-xs font-medium text-obsidian-danger bg-transparent">Failed</span> |
| </td> |
| </tr> |
| <tr> |
| <td className="px-4 py-3 whitespace-nowrap text-sm font-mono text-obsidian-text">TXN-0978-E</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm text-obsidian-muted">Oct 24, 09:45:00</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm font-mono text-right text-obsidian-text">$2,100.00</td> |
| <td className="px-4 py-3 whitespace-nowrap text-sm text-obsidian-text">Globex</td> |
| <td className="px-4 py-3 whitespace-nowrap"> |
| <span className="inline-flex items-center px-2 py-0.5 border border-obsidian-success text-xs font-medium text-obsidian-success bg-transparent">Completed</span> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| </motion.section> |
| {/* END: Survival Curve Chart */} |
| {/* BEGIN: PayoutControls */} |
| <section aria-label="Payout Controls" className="lg:col-span-1 space-y-4"> |
| <h2 className="text-sm font-semibold text-obsidian-text uppercase tracking-wide">Manual Payout</h2> |
| <div className="precision-panel p-6"> |
| <form className="space-y-5" onsubmit="event.preventDefault();"> |
| {/* Amount Input */} |
| <div> |
| <label className="block text-xs font-medium text-obsidian-muted mb-1 uppercase" htmlFor="payout-amount">Amount (USD)</label> |
| <div className="relative mt-1"> |
| <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none"> |
| <span className="text-obsidian-muted sm:text-sm">$</span> |
| </div> |
| <input className="precision-input block w-full pl-7 pr-12 sm:text-sm font-mono py-2" id="payout-amount" name="amount" placeholder="0.00" step="0.01" type="number"/> |
| <div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none"> |
| <span className="text-obsidian-muted sm:text-sm" id="price-currency">USD</span> |
| </div> |
| </div> |
| </div> |
| {/* Destination Select */} |
| <div> |
| <label className="block text-xs font-medium text-obsidian-muted mb-1 uppercase" htmlFor="payout-destination">Destination Account</label> |
| <select className="precision-input mt-1 block w-full pl-3 pr-10 py-2 text-base sm:text-sm" id="payout-destination" name="destination"> |
| <option>Select an account...</option> |
| <option>Acme Corp (**** 1234)</option> |
| <option>Stark Ind. (**** 9876)</option> |
| <option>Wayne Ent. (**** 4567)</option> |
| </select> |
| </div> |
| {/* Priority Toggle */} |
| <div className="flex items-center justify-between pt-2"> |
| <span className="flex-grow flex flex-col"> |
| <span className="text-sm font-medium text-obsidian-text" id="priority-label">Priority Processing</span> |
| <span className="text-xs text-obsidian-muted" id="priority-description">Incurs additional $15 fee</span> |
| </span> |
| {/* Custom Toggle Switch */} |
| <button aria-checked="false" className="relative inline-flex flex-shrink-0 h-6 w-11 border border-obsidian-border bg-obsidian-bg cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none" role="switch" type="button"> |
| <span aria-hidden="true" className="pointer-events-none inline-block h-5 w-5 bg-obsidian-muted transform ring-0 transition ease-in-out duration-200 translate-x-0"></span> |
| </button> |
| </div> |
| {/* Submit Button */} |
| <div className="pt-4 border-t border-obsidian-border"> |
| <button className="precision-button-primary w-full flex justify-center py-2 px-4 text-sm font-medium focus:outline-none uppercase tracking-wider" type="submit"> |
| Initiate Payout |
| </button> |
| </div> |
| </form> |
| </div> |
| {/* System Status Widget */} |
| <div className="precision-panel p-4 flex items-center justify-between"> |
| <div className="flex items-center"> |
| <div className="w-2 h-2 bg-obsidian-success rounded-full mr-3"></div> |
| <span className="text-sm text-obsidian-text">Payment Gateway API</span> |
| </div> |
| <span className="text-xs font-mono text-obsidian-success">Operational</span> |
| </div> |
| </section> |
| {/* END: PayoutControls */} |
| </div> |
| {/* END: Main Content Grid */} |
| </div> |
| </div> |
| </main> |
| {/* END: MainContent */} |
| |
| </> |
| ); |
| }; |
|
|
| export default FinancialOpsAdmin; |
|
|