update component and responsive all pages
This commit is contained in:
parent
4785ef2aaa
commit
6dee2e5b3a
10 changed files with 448 additions and 202 deletions
|
|
@ -1,10 +1,10 @@
|
|||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<link rel="icon" type="image/svg+xml" href="/planpost.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>affiliate-planpost</title>
|
||||
<title>Planpost Affiliate</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
|
|
|||
18
package-lock.json
generated
18
package-lock.json
generated
|
|
@ -71,6 +71,7 @@
|
|||
"integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.3",
|
||||
|
|
@ -2305,6 +2306,7 @@
|
|||
"integrity": "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~7.12.0"
|
||||
}
|
||||
|
|
@ -2315,6 +2317,7 @@
|
|||
"integrity": "sha512-+kLxJpaJzXybyDyFXYADyP1cznTO8HSuBpenGlnKOAkH4hyNINiywvXS/tGJhsrGGP/gM185RA3xpjY0Yg4erA==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
|
|
@ -2325,6 +2328,7 @@
|
|||
"integrity": "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.0.0"
|
||||
}
|
||||
|
|
@ -2381,6 +2385,7 @@
|
|||
"integrity": "sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.44.1",
|
||||
"@typescript-eslint/types": "8.44.1",
|
||||
|
|
@ -2633,6 +2638,7 @@
|
|||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
|
|
@ -2763,6 +2769,7 @@
|
|||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.8.3",
|
||||
"caniuse-lite": "^1.0.30001741",
|
||||
|
|
@ -3187,6 +3194,7 @@
|
|||
"integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.8.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
|
|
@ -4320,6 +4328,7 @@
|
|||
"resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
|
||||
"integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
|
@ -4329,6 +4338,7 @@
|
|||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz",
|
||||
"integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"scheduler": "^0.26.0"
|
||||
},
|
||||
|
|
@ -4348,6 +4358,7 @@
|
|||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
||||
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/use-sync-external-store": "^0.0.6",
|
||||
"use-sync-external-store": "^1.4.0"
|
||||
|
|
@ -4514,7 +4525,8 @@
|
|||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
||||
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/redux-thunk": {
|
||||
"version": "3.1.0",
|
||||
|
|
@ -4795,6 +4807,7 @@
|
|||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
|
|
@ -4863,6 +4876,7 @@
|
|||
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
|
|
@ -5022,6 +5036,7 @@
|
|||
"resolved": "https://registry.npmjs.org/vite/-/vite-7.1.7.tgz",
|
||||
"integrity": "sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"fdir": "^6.5.0",
|
||||
|
|
@ -5113,6 +5128,7 @@
|
|||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
|
|
|
|||
BIN
public/planpost.png
Normal file
BIN
public/planpost.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 164 KiB |
119
public/planpost.svg
Normal file
119
public/planpost.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -1,3 +1,4 @@
|
|||
import React from "react";
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarContent,
|
||||
|
|
@ -9,13 +10,7 @@ import {
|
|||
SidebarHeader,
|
||||
SidebarFooter,
|
||||
} from "@/components/ui/sidebar";
|
||||
import {
|
||||
LayoutDashboard,
|
||||
Users,
|
||||
DollarSign,
|
||||
LogOut,
|
||||
Sparkles,
|
||||
} from "lucide-react";
|
||||
import { LayoutDashboard, Users, DollarSign, LogOut } from "lucide-react";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
|
||||
const AppSidebar: React.FC = () => {
|
||||
|
|
@ -31,8 +26,8 @@ const AppSidebar: React.FC = () => {
|
|||
<Sidebar className="border-r bg-gradient-to-b from-slate-50 to-white">
|
||||
<SidebarHeader className="border-b border-gray-200 pb-4">
|
||||
<div className="flex items-center gap-3 px-2">
|
||||
<div className="bg-gradient-to-br from-blue-500 to-purple-600 p-2.5 rounded-lg shadow-md">
|
||||
<Sparkles className="w-5 h-5 text-white" />
|
||||
<div>
|
||||
<img src="/planpost.png" alt="Logo" className="w-10 h-10" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-lg font-bold text-gray-900">Affiliate Panel</h2>
|
||||
|
|
@ -54,7 +49,7 @@ const AppSidebar: React.FC = () => {
|
|||
transition-all duration-200
|
||||
${
|
||||
pathname === path
|
||||
? " text-white shadow-md hover:shadow-lg"
|
||||
? "bg-blue-600 text-white shadow-md hover:bg-blue-700"
|
||||
: "hover:bg-gray-100 text-gray-700"
|
||||
}
|
||||
`}
|
||||
|
|
@ -78,7 +73,6 @@ const AppSidebar: React.FC = () => {
|
|||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
|
||||
{/* Stats Card */}
|
||||
<div className="mt-6 mx-2 bg-gradient-to-br from-blue-50 to-purple-50 border border-blue-100 rounded-xl p-4">
|
||||
<p className="text-xs font-medium text-gray-600 mb-2">
|
||||
Total Earnings
|
||||
|
|
@ -103,7 +97,6 @@ const AppSidebar: React.FC = () => {
|
|||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
|
||||
{/* User Profile */}
|
||||
<div className="mt-3 mx-2 flex items-center gap-3 p-3 bg-gray-50 rounded-lg border border-gray-200">
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-blue-500 to-purple-600 rounded-full flex items-center justify-center text-white font-semibold">
|
||||
JD
|
||||
|
|
|
|||
|
|
@ -1,16 +1,24 @@
|
|||
import React from "react";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import AppSidebar from "../Sidebar";
|
||||
import { SidebarProvider, SidebarInset } from "../ui/sidebar";
|
||||
import { SidebarProvider, SidebarInset, SidebarTrigger } from "../ui/sidebar";
|
||||
|
||||
const DashboardLayout: React.FC = () => {
|
||||
return (
|
||||
<SidebarProvider>
|
||||
<AppSidebar />
|
||||
<SidebarInset>
|
||||
<main className="flex-1 p-6 bg-gray-50">
|
||||
<Outlet />
|
||||
</main>
|
||||
<div className="flex-1">
|
||||
{/* Mobile Header with Sidebar Trigger */}
|
||||
<header className="sticky top-0 z-10 flex h-[70px] items-center gap-2 px-2">
|
||||
<SidebarTrigger className="hover:bg-gray-100" />
|
||||
</header>
|
||||
|
||||
{/* Main Content */}
|
||||
<main className="flex-1 p-6 bg-gray-50">
|
||||
<Outlet />
|
||||
</main>
|
||||
</div>
|
||||
</SidebarInset>
|
||||
</SidebarProvider>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -134,43 +134,48 @@ const Earnings: React.FC = () => {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 p-6">
|
||||
<div className="min-h-screen bg-gray-50 p-4 sm:p-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
{/* Header */}
|
||||
<div className="mb-8 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
|
||||
<div className="mb-6 sm:mb-8 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-2">Earnings</h1>
|
||||
<p className="text-gray-600">
|
||||
<h1 className="text-2xl sm:text-3xl font-bold text-gray-900 mb-2">
|
||||
Earnings
|
||||
</h1>
|
||||
<p className="text-sm sm:text-base text-gray-600">
|
||||
Track your affiliate performance and payouts
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex gap-3">
|
||||
<button className="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors flex items-center gap-2">
|
||||
<Download className="w-5 h-5 text-gray-600" />
|
||||
Export
|
||||
<div className="flex gap-2 sm:gap-3">
|
||||
<button className="flex-1 sm:flex-initial px-3 sm:px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors flex items-center justify-center gap-2 text-sm sm:text-base">
|
||||
<Download className="w-4 h-4 sm:w-5 sm:h-5 text-gray-600" />
|
||||
<span className="hidden sm:inline">Export</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setShowPayoutModal(true)}
|
||||
className="px-6 py-2 bg-gradient-to-r from-indigo-600 to-purple-600 text-white rounded-lg hover:from-indigo-700 hover:to-purple-700 transition-all shadow-md flex items-center gap-2"
|
||||
className="flex-1 sm:flex-initial px-4 sm:px-6 py-2 bg-gradient-to-r from-indigo-600 to-purple-600 text-white rounded-lg hover:from-indigo-700 hover:to-purple-700 transition-all shadow-md flex items-center justify-center gap-2 text-sm sm:text-base"
|
||||
>
|
||||
<CreditCard className="w-5 h-5" />
|
||||
Request Payout
|
||||
<CreditCard className="w-4 h-4 sm:w-5 sm:h-5" />
|
||||
<span className="hidden sm:inline">Request Payout</span>
|
||||
<span className="sm:hidden">Payout</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 sm:gap-6 mb-6 sm:mb-8">
|
||||
{stats.map((stat, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="bg-white rounded-xl shadow-sm border border-gray-100 p-6 hover:shadow-md transition-shadow"
|
||||
className="bg-white rounded-xl shadow-sm border border-gray-100 p-4 sm:p-6 hover:shadow-md transition-shadow"
|
||||
>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center justify-between mb-3 sm:mb-4">
|
||||
<div
|
||||
className={`${stat.bgColor} w-12 h-12 rounded-lg flex items-center justify-center`}
|
||||
className={`${stat.bgColor} w-10 h-10 sm:w-12 sm:h-12 rounded-lg flex items-center justify-center`}
|
||||
>
|
||||
<stat.icon className={`w-6 h-6 ${stat.textColor}`} />
|
||||
<stat.icon
|
||||
className={`w-5 h-5 sm:w-6 sm:h-6 ${stat.textColor}`}
|
||||
/>
|
||||
</div>
|
||||
{stat.trend !== "neutral" && (
|
||||
<div
|
||||
|
|
@ -179,18 +184,22 @@ const Earnings: React.FC = () => {
|
|||
}`}
|
||||
>
|
||||
{stat.trend === "up" ? (
|
||||
<ArrowUpRight className="w-4 h-4" />
|
||||
<ArrowUpRight className="w-3 h-3 sm:w-4 sm:h-4" />
|
||||
) : (
|
||||
<ArrowDownRight className="w-4 h-4" />
|
||||
<ArrowDownRight className="w-3 h-3 sm:w-4 sm:h-4" />
|
||||
)}
|
||||
<span className="text-sm font-semibold">{stat.change}</span>
|
||||
<span className="text-xs sm:text-sm font-semibold">
|
||||
{stat.change}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-3xl font-bold text-gray-900 mb-1">
|
||||
<div className="text-2xl sm:text-3xl font-bold text-gray-900 mb-1">
|
||||
{stat.value}
|
||||
</div>
|
||||
<div className="text-sm text-gray-600">{stat.label}</div>
|
||||
<div className="text-xs sm:text-sm text-gray-600">
|
||||
{stat.label}
|
||||
</div>
|
||||
{stat.trend === "neutral" && (
|
||||
<div className="text-xs text-gray-500 mt-1">{stat.change}</div>
|
||||
)}
|
||||
|
|
@ -199,45 +208,45 @@ const Earnings: React.FC = () => {
|
|||
</div>
|
||||
|
||||
{/* Next Payout Card */}
|
||||
<div className="bg-gradient-to-r from-indigo-600 to-purple-600 rounded-xl p-6 mb-8 shadow-lg">
|
||||
<div className="bg-gradient-to-r from-indigo-600 to-purple-600 rounded-xl p-4 sm:p-6 mb-6 sm:mb-8 shadow-lg">
|
||||
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-14 h-14 bg-white bg-opacity-20 backdrop-blur-sm rounded-xl flex items-center justify-center">
|
||||
<Calendar className="w-7 h-7 text-white" />
|
||||
<div className="flex items-start gap-3 sm:gap-4">
|
||||
<div className="w-12 h-12 sm:w-14 sm:h-14 bg-white bg-opacity-20 backdrop-blur-sm rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<Calendar className="w-6 h-6 sm:w-7 sm:h-7 text-black" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-indigo-100 text-sm mb-1">
|
||||
<div className="text-indigo-100 text-xs sm:text-sm mb-1">
|
||||
Next Scheduled Payout
|
||||
</div>
|
||||
<div className="text-3xl font-bold text-white mb-2">
|
||||
<div className="text-xl sm:text-3xl font-bold text-white mb-2">
|
||||
October 15, 2025
|
||||
</div>
|
||||
<div className="text-indigo-100 text-sm">
|
||||
<div className="text-indigo-100 text-xs sm:text-sm">
|
||||
Your earnings will be processed automatically
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-white bg-opacity-20 backdrop-blur-sm rounded-xl p-4 text-center md:text-right">
|
||||
<div className="text-indigo-100 text-sm mb-1">
|
||||
<div className="text-black text-xs sm:text-sm mb-1">
|
||||
Estimated Amount
|
||||
</div>
|
||||
<div className="text-4xl font-bold text-white">$450</div>
|
||||
<div className="text-indigo-100 text-xs mt-1">
|
||||
+ pending approvals
|
||||
<div className="text-3xl sm:text-4xl font-bold text-black">
|
||||
$450
|
||||
</div>
|
||||
<div className="text-black text-xs mt-1">+ pending approvals</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6 sm:mb-8">
|
||||
{/* Chart Section */}
|
||||
<div className="lg:col-span-2 bg-white rounded-xl shadow-sm border border-gray-100 p-6">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div className="lg:col-span-2 bg-white rounded-xl shadow-sm border border-gray-100 p-4 sm:p-6">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between mb-4 sm:mb-6 gap-3">
|
||||
<div>
|
||||
<h2 className="text-xl font-semibold text-gray-900">
|
||||
<h2 className="text-lg sm:text-xl font-semibold text-gray-900">
|
||||
Earnings Overview
|
||||
</h2>
|
||||
<p className="text-sm text-gray-600 mt-1">
|
||||
<p className="text-xs sm:text-sm text-gray-600 mt-1">
|
||||
Your performance over time
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -246,7 +255,7 @@ const Earnings: React.FC = () => {
|
|||
<button
|
||||
key={period}
|
||||
onClick={() => setTimeframe(period)}
|
||||
className={`px-3 py-1.5 rounded-lg text-sm font-medium transition-colors ${
|
||||
className={`px-2.5 sm:px-3 py-1.5 rounded-lg text-xs sm:text-sm font-medium transition-colors ${
|
||||
timeframe === period
|
||||
? "bg-indigo-600 text-white"
|
||||
: "bg-gray-100 text-gray-600 hover:bg-gray-200"
|
||||
|
|
@ -257,7 +266,7 @@ const Earnings: React.FC = () => {
|
|||
))}
|
||||
</div>
|
||||
</div>
|
||||
<ResponsiveContainer width="100%" height={300}>
|
||||
<ResponsiveContainer width="100%" height={250}>
|
||||
<AreaChart data={earningsData}>
|
||||
<defs>
|
||||
<linearGradient id="colorAmount" x1="0" y1="0" x2="0" y2="1">
|
||||
|
|
@ -269,9 +278,9 @@ const Earnings: React.FC = () => {
|
|||
<XAxis
|
||||
dataKey="date"
|
||||
stroke="#9ca3af"
|
||||
style={{ fontSize: "12px" }}
|
||||
style={{ fontSize: "10px" }}
|
||||
/>
|
||||
<YAxis stroke="#9ca3af" style={{ fontSize: "12px" }} />
|
||||
<YAxis stroke="#9ca3af" style={{ fontSize: "10px" }} />
|
||||
<Tooltip
|
||||
contentStyle={{
|
||||
backgroundColor: "#fff",
|
||||
|
|
@ -284,7 +293,7 @@ const Earnings: React.FC = () => {
|
|||
type="monotone"
|
||||
dataKey="amount"
|
||||
stroke="#6366f1"
|
||||
strokeWidth={3}
|
||||
strokeWidth={2}
|
||||
fill="url(#colorAmount)"
|
||||
/>
|
||||
</AreaChart>
|
||||
|
|
@ -292,46 +301,60 @@ const Earnings: React.FC = () => {
|
|||
</div>
|
||||
|
||||
{/* Payment Methods */}
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-6">
|
||||
<h2 className="text-xl font-semibold text-gray-900 mb-4">
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-4 sm:p-6">
|
||||
<h2 className="text-lg sm:text-xl font-semibold text-gray-900 mb-4">
|
||||
Payment Method
|
||||
</h2>
|
||||
<div className="space-y-3">
|
||||
<div className="p-4 border-2 border-indigo-600 rounded-lg bg-indigo-50">
|
||||
<div className="p-3 sm:p-4 border-2 border-indigo-600 rounded-lg bg-indigo-50">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<div className="w-10 h-10 bg-indigo-600 rounded-lg flex items-center justify-center">
|
||||
<CreditCard className="w-5 h-5 text-white" />
|
||||
<div className="w-9 h-9 sm:w-10 sm:h-10 bg-indigo-600 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<CreditCard className="w-4 h-4 sm:w-5 sm:h-5 text-white" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className="font-semibold text-gray-900">PayPal</div>
|
||||
<div className="text-sm text-gray-600">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="font-semibold text-gray-900 text-sm sm:text-base">
|
||||
PayPal
|
||||
</div>
|
||||
<div className="text-xs sm:text-sm text-gray-600 truncate">
|
||||
john@example.com
|
||||
</div>
|
||||
</div>
|
||||
<CheckCircle className="w-5 h-5 text-indigo-600" />
|
||||
<CheckCircle className="w-4 h-4 sm:w-5 sm:h-5 text-indigo-600 flex-shrink-0" />
|
||||
</div>
|
||||
</div>
|
||||
<button className="w-full p-4 border-2 border-dashed border-gray-300 rounded-lg text-gray-600 hover:border-indigo-600 hover:text-indigo-600 transition-colors font-medium">
|
||||
<button className="w-full p-3 sm:p-4 border-2 border-dashed border-gray-300 rounded-lg text-gray-600 hover:border-indigo-600 hover:text-indigo-600 transition-colors font-medium text-sm sm:text-base">
|
||||
+ Add Payment Method
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 pt-6 border-t border-gray-100">
|
||||
<h3 className="font-semibold text-gray-900 mb-3">Quick Stats</h3>
|
||||
<div className="mt-4 sm:mt-6 pt-4 sm:pt-6 border-t border-gray-100">
|
||||
<h3 className="font-semibold text-gray-900 mb-3 text-sm sm:text-base">
|
||||
Quick Stats
|
||||
</h3>
|
||||
<div className="space-y-3">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm text-gray-600">
|
||||
<span className="text-xs sm:text-sm text-gray-600">
|
||||
Total Transactions
|
||||
</span>
|
||||
<span className="font-semibold text-gray-900">142</span>
|
||||
<span className="font-semibold text-gray-900 text-sm sm:text-base">
|
||||
142
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm text-gray-600">Avg. Commission</span>
|
||||
<span className="font-semibold text-gray-900">$87.68</span>
|
||||
<span className="text-xs sm:text-sm text-gray-600">
|
||||
Avg. Commission
|
||||
</span>
|
||||
<span className="font-semibold text-gray-900 text-sm sm:text-base">
|
||||
$87.68
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm text-gray-600">Success Rate</span>
|
||||
<span className="font-semibold text-green-600">98.2%</span>
|
||||
<span className="text-xs sm:text-sm text-gray-600">
|
||||
Success Rate
|
||||
</span>
|
||||
<span className="font-semibold text-green-600 text-sm sm:text-base">
|
||||
98.2%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -340,39 +363,42 @@ const Earnings: React.FC = () => {
|
|||
|
||||
{/* Transaction History */}
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100">
|
||||
<div className="p-6 border-b border-gray-100">
|
||||
<h2 className="text-xl font-semibold text-gray-900">
|
||||
<div className="p-4 sm:p-6 border-b border-gray-100">
|
||||
<h2 className="text-lg sm:text-xl font-semibold text-gray-900">
|
||||
Recent Transactions
|
||||
</h2>
|
||||
<p className="text-sm text-gray-600 mt-1">
|
||||
<p className="text-xs sm:text-sm text-gray-600 mt-1">
|
||||
Your latest earnings and payouts
|
||||
</p>
|
||||
</div>
|
||||
<div className="divide-y divide-gray-100">
|
||||
{transactionData.map((transaction, idx) => (
|
||||
<div key={idx} className="p-6 hover:bg-gray-50 transition-colors">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-4">
|
||||
<div
|
||||
key={idx}
|
||||
className="p-4 sm:p-6 hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-3 sm:gap-4 min-w-0">
|
||||
<div
|
||||
className={`w-12 h-12 rounded-xl flex items-center justify-center ${
|
||||
className={`w-10 h-10 sm:w-12 sm:h-12 rounded-xl flex items-center justify-center flex-shrink-0 ${
|
||||
transaction.type === "Bonus"
|
||||
? "bg-purple-100"
|
||||
: "bg-green-100"
|
||||
}`}
|
||||
>
|
||||
<DollarSign
|
||||
className={`w-6 h-6 ${
|
||||
className={`w-5 h-5 sm:w-6 sm:h-6 ${
|
||||
transaction.type === "Bonus"
|
||||
? "text-purple-600"
|
||||
: "text-green-600"
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-semibold text-gray-900">
|
||||
<div className="min-w-0">
|
||||
<div className="font-semibold text-gray-900 text-sm sm:text-base">
|
||||
{transaction.type}
|
||||
</div>
|
||||
<div className="text-sm text-gray-600">
|
||||
<div className="text-xs sm:text-sm text-gray-600">
|
||||
{transaction.date}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500 mt-1">
|
||||
|
|
@ -380,12 +406,12 @@ const Earnings: React.FC = () => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-2xl font-bold text-gray-900">
|
||||
<div className="text-right flex-shrink-0">
|
||||
<div className="text-lg sm:text-2xl font-bold text-gray-900">
|
||||
{transaction.amount}
|
||||
</div>
|
||||
<span
|
||||
className={`inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-semibold mt-1 ${
|
||||
className={`inline-flex items-center gap-1 px-2 py-0.5 sm:py-1 rounded-full text-xs font-semibold mt-1 ${
|
||||
transaction.status === "Completed"
|
||||
? "bg-green-100 text-green-700"
|
||||
: "bg-yellow-100 text-yellow-700"
|
||||
|
|
@ -396,15 +422,17 @@ const Earnings: React.FC = () => {
|
|||
) : (
|
||||
<Clock className="w-3 h-3" />
|
||||
)}
|
||||
{transaction.status}
|
||||
<span className="hidden sm:inline">
|
||||
{transaction.status}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="p-6 border-t border-gray-100 text-center">
|
||||
<button className="text-indigo-600 hover:text-indigo-700 font-semibold text-sm">
|
||||
<div className="p-4 sm:p-6 border-t border-gray-100 text-center">
|
||||
<button className="text-indigo-600 hover:text-indigo-700 font-semibold text-xs sm:text-sm">
|
||||
View All Transactions →
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -413,19 +441,19 @@ const Earnings: React.FC = () => {
|
|||
|
||||
{/* Payout Request Modal */}
|
||||
{showPayoutModal && (
|
||||
<div className="fixed inset-0 bg-black/20 bg-opacity-50 flex items-center justify-center z-50 p-4">
|
||||
<div className="bg-white rounded-2xl shadow-2xl h-[80vh] overflow-y-auto max-w-md w-full animate-fade-in">
|
||||
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
|
||||
<div className="bg-white rounded-2xl shadow-2xl max-h-[90vh] overflow-y-auto max-w-md w-full animate-fade-in">
|
||||
{/* Modal Header */}
|
||||
<div className="flex items-center justify-between p-6 border-b border-gray-100">
|
||||
<div className="flex items-center justify-between p-4 sm:p-6 border-b border-gray-100">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-12 h-12 bg-gradient-to-br from-indigo-500 to-purple-500 rounded-xl flex items-center justify-center">
|
||||
<Wallet className="w-6 h-6 text-white" />
|
||||
<div className="w-10 h-10 sm:w-12 sm:h-12 bg-gradient-to-br from-indigo-500 to-purple-500 rounded-xl flex items-center justify-center">
|
||||
<Wallet className="w-5 h-5 sm:w-6 sm:h-6 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold text-gray-900">
|
||||
<h3 className="text-lg sm:text-xl font-bold text-gray-900">
|
||||
Request Payout
|
||||
</h3>
|
||||
<p className="text-sm text-gray-600">
|
||||
<p className="text-xs sm:text-sm text-gray-600">
|
||||
Withdraw your earnings
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -439,13 +467,15 @@ const Earnings: React.FC = () => {
|
|||
</div>
|
||||
|
||||
{/* Modal Body */}
|
||||
<div className="p-6 space-y-5">
|
||||
<div className="p-4 sm:p-6 space-y-4 sm:space-y-5">
|
||||
{/* Available Balance */}
|
||||
<div className="bg-gradient-to-br from-green-50 to-emerald-50 border border-green-200 rounded-xl p-4">
|
||||
<div className="text-sm text-green-700 mb-1">
|
||||
<div className="text-xs sm:text-sm text-green-700 mb-1">
|
||||
Available Balance
|
||||
</div>
|
||||
<div className="text-3xl font-bold text-green-900">$890.00</div>
|
||||
<div className="text-2xl sm:text-3xl font-bold text-green-900">
|
||||
$890.00
|
||||
</div>
|
||||
<div className="text-xs text-green-600 mt-1">
|
||||
Ready for withdrawal
|
||||
</div>
|
||||
|
|
@ -464,11 +494,11 @@ const Earnings: React.FC = () => {
|
|||
onChange={(e) => setPayoutAmount(e.target.value)}
|
||||
placeholder="0.00"
|
||||
max="890"
|
||||
className="w-full pl-10 pr-20 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent outline-none text-lg font-semibold"
|
||||
className="w-full pl-10 pr-16 sm:pr-20 py-2.5 sm:py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent outline-none text-base sm:text-lg font-semibold"
|
||||
/>
|
||||
<button
|
||||
onClick={() => setPayoutAmount("890")}
|
||||
className="absolute right-2 top-1/2 transform -translate-y-1/2 px-3 py-1 bg-indigo-600 text-white text-sm rounded-md hover:bg-indigo-700 transition-colors"
|
||||
className="absolute right-2 top-1/2 transform -translate-y-1/2 px-2.5 sm:px-3 py-1 bg-indigo-600 text-white text-xs sm:text-sm rounded-md hover:bg-indigo-700 transition-colors"
|
||||
>
|
||||
Max
|
||||
</button>
|
||||
|
|
@ -483,14 +513,16 @@ const Earnings: React.FC = () => {
|
|||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
Payment Method
|
||||
</label>
|
||||
<div className="p-4 border-2 border-indigo-600 rounded-lg bg-indigo-50">
|
||||
<div className="p-3 sm:p-4 border-2 border-indigo-600 rounded-lg bg-indigo-50">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 bg-indigo-600 rounded-lg flex items-center justify-center">
|
||||
<CreditCard className="w-5 h-5 text-white" />
|
||||
<div className="w-9 h-9 sm:w-10 sm:h-10 bg-indigo-600 rounded-lg flex items-center justify-center">
|
||||
<CreditCard className="w-4 h-4 sm:w-5 sm:h-5 text-white" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className="font-semibold text-gray-900">PayPal</div>
|
||||
<div className="text-sm text-gray-600">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="font-semibold text-gray-900 text-sm sm:text-base">
|
||||
PayPal
|
||||
</div>
|
||||
<div className="text-xs sm:text-sm text-gray-600 truncate">
|
||||
john@example.com
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -500,9 +532,9 @@ const Earnings: React.FC = () => {
|
|||
</div>
|
||||
|
||||
{/* Processing Info */}
|
||||
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4 flex gap-3">
|
||||
<div className="bg-blue-50 border border-blue-200 rounded-lg p-3 sm:p-4 flex gap-3">
|
||||
<AlertCircle className="w-5 h-5 text-blue-600 flex-shrink-0 mt-0.5" />
|
||||
<div className="text-sm text-blue-700">
|
||||
<div className="text-xs sm:text-sm text-blue-700">
|
||||
<p className="font-medium mb-1">Processing Time</p>
|
||||
<p className="text-blue-600">
|
||||
Payouts are typically processed within 24-48 hours on
|
||||
|
|
@ -512,22 +544,22 @@ const Earnings: React.FC = () => {
|
|||
</div>
|
||||
|
||||
{/* Summary */}
|
||||
<div className="bg-gray-50 rounded-lg p-4 space-y-2">
|
||||
<div className="flex justify-between text-sm">
|
||||
<div className="bg-gray-50 rounded-lg p-3 sm:p-4 space-y-2">
|
||||
<div className="flex justify-between text-xs sm:text-sm">
|
||||
<span className="text-gray-600">Withdrawal Amount</span>
|
||||
<span className="font-semibold text-gray-900">
|
||||
${payoutAmount}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-sm">
|
||||
<div className="flex justify-between text-xs sm:text-sm">
|
||||
<span className="text-gray-600">Processing Fee</span>
|
||||
<span className="font-semibold text-gray-900">$0.00</span>
|
||||
</div>
|
||||
<div className="border-t border-gray-200 pt-2 flex justify-between">
|
||||
<span className="font-semibold text-gray-900">
|
||||
<span className="font-semibold text-gray-900 text-sm sm:text-base">
|
||||
You'll Receive
|
||||
</span>
|
||||
<span className="text-xl font-bold text-indigo-600">
|
||||
<span className="text-lg sm:text-xl font-bold text-indigo-600">
|
||||
${payoutAmount}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -535,10 +567,10 @@ const Earnings: React.FC = () => {
|
|||
</div>
|
||||
|
||||
{/* Modal Footer */}
|
||||
<div className="p-6 border-t border-gray-100 flex gap-3">
|
||||
<div className="p-4 sm:p-6 border-t border-gray-100 flex gap-3">
|
||||
<button
|
||||
onClick={() => setShowPayoutModal(false)}
|
||||
className="flex-1 px-4 py-3 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors font-semibold text-gray-700"
|
||||
className="flex-1 px-3 sm:px-4 py-2.5 sm:py-3 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors font-semibold text-gray-700 text-sm sm:text-base"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
|
|
@ -549,15 +581,15 @@ const Earnings: React.FC = () => {
|
|||
Number(payoutAmount) < 50 ||
|
||||
Number(payoutAmount) > 890
|
||||
}
|
||||
className="flex-1 px-4 py-3 bg-gradient-to-r from-indigo-600 to-purple-600 text-white rounded-lg hover:from-indigo-700 hover:to-purple-700 transition-all font-semibold disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2"
|
||||
className="flex-1 px-3 sm:px-4 py-2.5 sm:py-3 bg-gradient-to-r from-indigo-600 to-purple-600 text-white rounded-lg hover:from-indigo-700 hover:to-purple-700 transition-all font-semibold disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 text-sm sm:text-base"
|
||||
>
|
||||
{isProcessing ? (
|
||||
<>
|
||||
<div className="w-5 h-5 border-2 border-white border-t-transparent rounded-full animate-spin"></div>
|
||||
Processing...
|
||||
<div className="w-4 h-4 sm:w-5 sm:h-5 border-2 border-white border-t-transparent rounded-full animate-spin"></div>
|
||||
<span className="hidden sm:inline">Processing...</span>
|
||||
</>
|
||||
) : (
|
||||
<>Confirm Request</>
|
||||
<>Confirm</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ const Login: React.FC = () => {
|
|||
|
||||
<div className="relative z-10">
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<div className="w-12 h-12 bg-white rounded-xl flex items-center justify-center">
|
||||
<TrendingUp className="w-7 h-7 text-indigo-600" />
|
||||
<div className="w-12 h-12 flex items-center justify-center">
|
||||
<img src="/planpost.png" alt="Logo" className="w-12 h-12" />
|
||||
</div>
|
||||
<span className="text-2xl font-bold text-white">
|
||||
Planpost Affiliate
|
||||
|
|
|
|||
|
|
@ -25,21 +25,25 @@ const MetricsCard = ({
|
|||
trend,
|
||||
bgColor,
|
||||
}: MetricsCardProps) => (
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-6 hover:shadow-md transition-shadow">
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<div className={`${bgColor} p-3 rounded-lg`}>
|
||||
<Icon className="w-6 h-6 text-white" />
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-4 sm:p-6 hover:shadow-md transition-shadow">
|
||||
<div className="flex items-start justify-between mb-3 sm:mb-4">
|
||||
<div className={`${bgColor} p-2 sm:p-3 rounded-lg`}>
|
||||
<Icon className="w-5 h-5 sm:w-6 sm:h-6 text-white" />
|
||||
</div>
|
||||
{trend && (
|
||||
<span className="flex items-center text-sm font-medium text-green-600 bg-green-50 px-2 py-1 rounded-full">
|
||||
<span className="flex items-center text-xs sm:text-sm font-medium text-green-600 bg-green-50 px-2 py-1 rounded-full">
|
||||
<TrendingUp className="w-3 h-3 mr-1" />
|
||||
{trend}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<h3 className="text-gray-600 text-sm font-medium mb-1">{title}</h3>
|
||||
<p className="text-2xl font-bold text-gray-900">{value}</p>
|
||||
{subtitle && <p className="text-sm text-gray-500 mt-1">{subtitle}</p>}
|
||||
<h3 className="text-gray-600 text-xs sm:text-sm font-medium mb-1">
|
||||
{title}
|
||||
</h3>
|
||||
<p className="text-xl sm:text-2xl font-bold text-gray-900">{value}</p>
|
||||
{subtitle && (
|
||||
<p className="text-xs sm:text-sm text-gray-500 mt-1">{subtitle}</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
@ -54,19 +58,19 @@ const Overview = () => {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-0">
|
||||
{/* Header */}
|
||||
<div className="mb-8">
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-2">
|
||||
<div className="mb-6 sm:mb-8">
|
||||
<h3 className="text-2xl sm:text-3xl font-bold text-gray-900 mb-2">
|
||||
Dashboard Overview
|
||||
</h1>
|
||||
<p className="text-gray-600">
|
||||
</h3>
|
||||
<p className="text-sm sm:text-base text-gray-600">
|
||||
Track your affiliate performance and earnings
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Metrics Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 sm:gap-6 mb-6 sm:mb-8">
|
||||
<MetricsCard
|
||||
title="Total Earnings"
|
||||
value="$3,200"
|
||||
|
|
@ -96,16 +100,16 @@ const Overview = () => {
|
|||
</div>
|
||||
|
||||
{/* Referral Link Section */}
|
||||
<div className="bg-gradient-to-br from-blue-50 to-indigo-50 rounded-xl p-6 shadow-sm border border-blue-100">
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<div className="bg-gradient-to-br from-blue-50 to-indigo-50 rounded-xl p-4 sm:p-6 shadow-sm border border-blue-100">
|
||||
<div className="flex items-center gap-2 mb-3 sm:mb-4">
|
||||
<div className="bg-blue-500 p-2 rounded-lg">
|
||||
<Users className="w-5 h-5 text-white" />
|
||||
<Users className="w-4 h-4 sm:w-5 sm:h-5 text-white" />
|
||||
</div>
|
||||
<h2 className="text-xl font-semibold text-gray-900">
|
||||
<h2 className="text-lg sm:text-xl font-semibold text-gray-900">
|
||||
Your Referral Link
|
||||
</h2>
|
||||
</div>
|
||||
<p className="text-gray-600 text-sm mb-4">
|
||||
<p className="text-gray-600 text-xs sm:text-sm mb-3 sm:mb-4">
|
||||
Share this link with your network to start earning commissions
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-3">
|
||||
|
|
@ -114,12 +118,12 @@ const Overview = () => {
|
|||
type="text"
|
||||
value={referralLink}
|
||||
readOnly
|
||||
className="w-full border-2 border-gray-200 rounded-lg px-4 py-3 bg-white focus:outline-none focus:border-blue-500 transition-colors font-mono text-sm"
|
||||
className="w-full border-2 border-gray-200 rounded-lg px-3 sm:px-4 py-2.5 sm:py-3 bg-white focus:outline-none focus:border-blue-500 transition-colors font-mono text-xs sm:text-sm"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
onClick={handleCopy}
|
||||
className={`px-6 py-3 rounded-lg font-medium transition-all flex items-center justify-center gap-2 min-w-[120px] ${
|
||||
className={`px-4 sm:px-6 py-2.5 sm:py-3 rounded-lg font-medium transition-all flex items-center justify-center gap-2 min-w-[100px] sm:min-w-[120px] text-sm sm:text-base ${
|
||||
copied
|
||||
? "bg-green-500 text-white"
|
||||
: "bg-blue-600 text-white hover:bg-blue-700 active:scale-95"
|
||||
|
|
@ -141,34 +145,38 @@ const Overview = () => {
|
|||
</div>
|
||||
|
||||
{/* Quick Stats */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-8">
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-6">
|
||||
<h3 className="text-sm font-medium text-gray-600 mb-3">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6 mt-6 sm:mt-8">
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-4 sm:p-6">
|
||||
<h3 className="text-xs sm:text-sm font-medium text-gray-600 mb-2 sm:mb-3">
|
||||
Conversion Rate
|
||||
</h3>
|
||||
<p className="text-3xl font-bold text-gray-900 mb-2">12.5%</p>
|
||||
<p className="text-2xl sm:text-3xl font-bold text-gray-900 mb-2">
|
||||
12.5%
|
||||
</p>
|
||||
<div className="w-full bg-gray-200 rounded-full h-2">
|
||||
<div
|
||||
className="bg-blue-500 h-2 rounded-full"
|
||||
className="bg-blue-500 h-2 rounded-full transition-all duration-500"
|
||||
style={{ width: "12.5%" }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-6">
|
||||
<h3 className="text-sm font-medium text-gray-600 mb-3">
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-4 sm:p-6">
|
||||
<h3 className="text-xs sm:text-sm font-medium text-gray-600 mb-2 sm:mb-3">
|
||||
Average Commission
|
||||
</h3>
|
||||
<p className="text-3xl font-bold text-gray-900">$37.65</p>
|
||||
<p className="text-sm text-green-600 mt-2">↑ $2.15 from last month</p>
|
||||
<p className="text-2xl sm:text-3xl font-bold text-gray-900">$37.65</p>
|
||||
<p className="text-xs sm:text-sm text-green-600 mt-2">
|
||||
↑ $2.15 from last month
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-6">
|
||||
<h3 className="text-sm font-medium text-gray-600 mb-3">
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-4 sm:p-6 sm:col-span-2 lg:col-span-1">
|
||||
<h3 className="text-xs sm:text-sm font-medium text-gray-600 mb-2 sm:mb-3">
|
||||
Next Payout
|
||||
</h3>
|
||||
<p className="text-3xl font-bold text-gray-900">$945</p>
|
||||
<p className="text-sm text-gray-500 mt-2">In 12 days</p>
|
||||
<p className="text-2xl sm:text-3xl font-bold text-gray-900">$945</p>
|
||||
<p className="text-xs sm:text-sm text-gray-500 mt-2">In 12 days</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -127,68 +127,72 @@ const Referrals: React.FC = () => {
|
|||
);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 p-6">
|
||||
<div className="min-h-screen bg-gray-50 p-4">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
{/* Header */}
|
||||
<div className="mb-8">
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-2">Referrals</h1>
|
||||
<p className="text-gray-600">
|
||||
<div className="mb-6 sm:mb-8">
|
||||
<h3 className="text-2xl sm:text-3xl font-bold text-gray-900 mb-2">
|
||||
Referrals
|
||||
</h3>
|
||||
<p className="text-sm sm:text-base text-gray-600">
|
||||
Track and manage your affiliate referrals
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Stats Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 sm:gap-6 mb-6 sm:mb-8">
|
||||
{stats.map((stat, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="bg-white rounded-xl shadow-sm border border-gray-100 p-6 hover:shadow-md transition-shadow"
|
||||
className="bg-white rounded-xl shadow-sm border border-gray-100 p-4 sm:p-6 hover:shadow-md transition-shadow"
|
||||
>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center justify-between mb-3 sm:mb-4">
|
||||
<div
|
||||
className={`${stat.color} w-12 h-12 rounded-lg flex items-center justify-center`}
|
||||
className={`${stat.color} w-10 h-10 sm:w-12 sm:h-12 rounded-lg flex items-center justify-center`}
|
||||
>
|
||||
<stat.icon className="w-6 h-6 text-white" />
|
||||
<stat.icon className="w-5 h-5 sm:w-6 sm:h-6 text-white" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-3xl font-bold text-gray-900 mb-1">
|
||||
<div className="text-2xl sm:text-3xl font-bold text-gray-900 mb-1">
|
||||
{stat.value}
|
||||
</div>
|
||||
<div className="text-sm text-gray-600 mb-2">{stat.label}</div>
|
||||
<div className="text-xs sm:text-sm text-gray-600 mb-2">
|
||||
{stat.label}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500">{stat.change}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Referral Link Section */}
|
||||
<div className="bg-gradient-to-r from-indigo-600 to-purple-600 rounded-xl p-6 mb-8 shadow-lg">
|
||||
<div className="bg-gradient-to-r from-indigo-600 to-purple-600 rounded-xl p-4 sm:p-6 mb-6 sm:mb-8 shadow-lg">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Link2 className="w-5 h-5 text-white" />
|
||||
<h3 className="text-lg font-semibold text-white">
|
||||
<Link2 className="w-4 h-4 sm:w-5 sm:h-5 text-white" />
|
||||
<h3 className="text-base sm:text-lg font-semibold text-white">
|
||||
Your Referral Link
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-indigo-100 text-sm mb-4">
|
||||
<p className="text-indigo-100 text-xs sm:text-sm mb-3 sm:mb-4">
|
||||
Share this link to earn commissions
|
||||
</p>
|
||||
<div className="flex gap-3">
|
||||
<div className="flex-1 bg-white bg-opacity-20 backdrop-blur-sm rounded-lg px-4 py-3 text-white font-mono text-sm">
|
||||
<div className="flex flex-col sm:flex-row gap-3">
|
||||
<div className="flex-1 bg-white bg-opacity-20 backdrop-blur-sm rounded-lg px-3 sm:px-4 py-2.5 sm:py-3 text-white font-mono text-xs sm:text-sm break-all">
|
||||
{referralLink}
|
||||
</div>
|
||||
<button
|
||||
onClick={handleCopy}
|
||||
className="bg-white text-indigo-600 px-6 py-3 rounded-lg font-semibold hover:bg-gray-50 transition-all flex items-center gap-2 shadow-md"
|
||||
className="bg-white text-indigo-600 px-4 sm:px-6 py-2.5 sm:py-3 rounded-lg font-semibold hover:bg-gray-50 transition-all flex items-center justify-center gap-2 shadow-md text-sm sm:text-base"
|
||||
>
|
||||
{copied ? (
|
||||
<>
|
||||
<CheckCircle className="w-5 h-5" />
|
||||
<CheckCircle className="w-4 h-4 sm:w-5 sm:h-5" />
|
||||
Copied!
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Copy className="w-5 h-5" />
|
||||
<Copy className="w-4 h-4 sm:w-5 sm:h-5" />
|
||||
Copy Link
|
||||
</>
|
||||
)}
|
||||
|
|
@ -201,36 +205,102 @@ const Referrals: React.FC = () => {
|
|||
{/* Table Section */}
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100">
|
||||
{/* Table Header */}
|
||||
<div className="p-6 border-b border-gray-100">
|
||||
<div className="p-4 sm:p-6 border-b border-gray-100">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
|
||||
<h2 className="text-xl font-semibold text-gray-900">
|
||||
<h2 className="text-lg sm:text-xl font-semibold text-gray-900">
|
||||
Referral List
|
||||
</h2>
|
||||
<div className="flex gap-3">
|
||||
<div className="flex gap-2 sm:gap-3">
|
||||
<div className="relative flex-1 sm:flex-initial">
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 sm:w-5 sm:h-5 text-gray-400" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search referrals..."
|
||||
placeholder="Search..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent outline-none w-full sm:w-64"
|
||||
className="pl-9 sm:pl-10 pr-3 sm:pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent outline-none w-full sm:w-64 text-sm"
|
||||
/>
|
||||
</div>
|
||||
<button className="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors flex items-center gap-2">
|
||||
<Filter className="w-5 h-5 text-gray-600" />
|
||||
<span className="hidden sm:inline">Filter</span>
|
||||
<button className="px-3 sm:px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors flex items-center gap-2">
|
||||
<Filter className="w-4 h-4 sm:w-5 sm:h-5 text-gray-600" />
|
||||
<span className="hidden sm:inline text-sm">Filter</span>
|
||||
</button>
|
||||
<button className="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors flex items-center gap-2">
|
||||
<Download className="w-5 h-5" />
|
||||
<span className="hidden sm:inline">Export</span>
|
||||
<button className="px-3 sm:px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors flex items-center gap-2">
|
||||
<Download className="w-4 h-4 sm:w-5 sm:h-5" />
|
||||
<span className="hidden sm:inline text-sm">Export</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Table */}
|
||||
<div className="overflow-x-auto">
|
||||
{/* Mobile Card View */}
|
||||
<div className="block lg:hidden">
|
||||
{filteredReferrals.map((r, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="p-4 border-b border-gray-100 hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
<div className="flex items-start justify-between mb-3">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-full bg-gradient-to-br from-indigo-500 to-purple-500 flex items-center justify-center text-white font-semibold text-sm">
|
||||
{r.name.charAt(0)}
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-semibold text-gray-900 text-sm">
|
||||
{r.name}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500">{r.email}</div>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
className={`inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-xs font-semibold ${
|
||||
r.status === "Active"
|
||||
? "bg-green-100 text-green-700"
|
||||
: "bg-yellow-100 text-yellow-700"
|
||||
}`}
|
||||
>
|
||||
{r.status === "Active" ? (
|
||||
<CheckCircle className="w-3 h-3" />
|
||||
) : (
|
||||
<Clock className="w-3 h-3" />
|
||||
)}
|
||||
{r.status}
|
||||
</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3 text-sm">
|
||||
<div>
|
||||
<div className="text-xs text-gray-500 mb-1">
|
||||
Signup Date
|
||||
</div>
|
||||
<div className="text-gray-700">{r.signupDate}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-xs text-gray-500 mb-1">Country</div>
|
||||
<div className="text-gray-700">{r.country}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-xs text-gray-500 mb-1">
|
||||
Last Earning
|
||||
</div>
|
||||
<div className="font-semibold text-gray-900">
|
||||
{r.earnings}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-xs text-gray-500 mb-1">
|
||||
Total Commission
|
||||
</div>
|
||||
<div className="font-semibold text-gray-900">
|
||||
{r.totalCommission}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Desktop Table View */}
|
||||
<div className="hidden lg:block overflow-x-auto">
|
||||
<table className="w-full">
|
||||
<thead className="bg-gray-50 border-b border-gray-100">
|
||||
<tr>
|
||||
|
|
@ -325,18 +395,18 @@ const Referrals: React.FC = () => {
|
|||
</div>
|
||||
|
||||
{/* Table Footer */}
|
||||
<div className="p-4 border-t border-gray-100 flex items-center justify-between">
|
||||
<div className="text-sm text-gray-600">
|
||||
<div className="p-4 border-t border-gray-100 flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<div className="text-xs sm:text-sm text-gray-600">
|
||||
Showing{" "}
|
||||
<span className="font-semibold">{filteredReferrals.length}</span>{" "}
|
||||
of <span className="font-semibold">{referrals.length}</span>{" "}
|
||||
referrals
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<button className="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors text-sm font-medium">
|
||||
<button className="px-3 sm:px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors text-xs sm:text-sm font-medium">
|
||||
Previous
|
||||
</button>
|
||||
<button className="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors text-sm font-medium">
|
||||
<button className="px-3 sm:px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors text-xs sm:text-sm font-medium">
|
||||
Next
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue