Added ShowcaseUI app
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
FileCheck2,
|
||||
UploadCloud,
|
||||
MessageSquare,
|
||||
KeyRound,
|
||||
CheckCircle,
|
||||
Clock,
|
||||
ShieldAlert,
|
||||
ExternalLink,
|
||||
Maximize2,
|
||||
FileSignature
|
||||
} from 'lucide-react';
|
||||
import { SCREENSHOTS, ScreenshotItem } from '../../data/showcaseData';
|
||||
|
||||
interface PartnerShowcaseProps {
|
||||
onOpenScreenshot: (item: ScreenshotItem) => void;
|
||||
}
|
||||
|
||||
export const PartnerShowcase: React.FC<PartnerShowcaseProps> = ({ onOpenScreenshot }) => {
|
||||
const partnerScreenshots = SCREENSHOTS.filter((s) => s.platform === 'PFM Partner');
|
||||
const [selectedCategory, setSelectedCategory] = useState<string>('All');
|
||||
|
||||
const categories = ['All', 'Dashboard', 'Evidence & Proof', 'Communications', 'Onboarding'];
|
||||
|
||||
const filteredScreens = selectedCategory === 'All'
|
||||
? partnerScreenshots
|
||||
: partnerScreenshots.filter((s) => s.category === selectedCategory);
|
||||
|
||||
return (
|
||||
<section id="partner-section" className="py-24 bg-slate-950 relative border-t border-slate-900 overflow-hidden">
|
||||
{/* Background ambient glow */}
|
||||
<div className="absolute top-1/4 right-0 w-96 h-96 bg-emerald-600/10 blur-[140px] rounded-full pointer-events-none -z-10" />
|
||||
<div className="absolute bottom-10 left-0 w-80 h-80 bg-teal-600/10 blur-[130px] rounded-full pointer-events-none -z-10" />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
{/* Section Header */}
|
||||
<div className="flex flex-col md:flex-row md:items-end justify-between gap-6 mb-16">
|
||||
<div className="max-w-3xl">
|
||||
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-emerald-500/10 border border-emerald-500/30 text-emerald-400 text-xs font-semibold mb-4">
|
||||
<FileCheck2 className="w-3.5 h-3.5" />
|
||||
<span>Grantee & Implementing Partner Suite</span>
|
||||
</div>
|
||||
<h2 className="text-3xl sm:text-4xl font-extrabold text-white tracking-tight leading-tight">
|
||||
PFM Partner •{' '}
|
||||
<span className="text-transparent bg-clip-text bg-gradient-to-r from-emerald-400 via-teal-400 to-cyan-400">
|
||||
Field Delivery & Evidence Hub
|
||||
</span>
|
||||
</h2>
|
||||
<p className="mt-3 text-base text-slate-300 leading-relaxed">
|
||||
Empower implementing teams to manage sanctioned grant agreements, execute work-breakdown activities, and upload tamper-evident proofs directly against funding covenants.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
<a
|
||||
href="https://partner.ifri.khongisa.co.za"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="px-4 py-2 rounded-xl bg-emerald-600/20 hover:bg-emerald-600/30 border border-emerald-500/40 text-emerald-300 hover:text-white text-xs font-semibold transition-all flex items-center gap-2 shadow-sm"
|
||||
>
|
||||
<span>Launch Live Partner Portal</span>
|
||||
<ExternalLink className="w-3.5 h-3.5" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 3 Core Partner Pillars */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-16">
|
||||
{/* Pillar 1 */}
|
||||
<div className="p-6 rounded-2xl bg-slate-900/60 border border-slate-800/80 hover:border-emerald-500/40 transition-all shadow-xl group">
|
||||
<div className="w-12 h-12 rounded-xl bg-emerald-500/10 border border-emerald-500/20 flex items-center justify-center text-emerald-400 mb-5 group-hover:scale-110 transition-transform">
|
||||
<UploadCloud className="w-6 h-6" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-xs font-mono font-semibold text-emerald-400">PILLAR 01</span>
|
||||
<span className="text-slate-600">•</span>
|
||||
<span className="text-xs text-slate-400">Evidence Vault</span>
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-white mb-2">
|
||||
Granular Activity Proof Uploads
|
||||
</h3>
|
||||
<p className="text-xs text-slate-300 leading-relaxed mb-4">
|
||||
Attach statutory documents, invoices, and geotagged photographs directly to milestones with pre-signed S3 storage and immediate SHA verification.
|
||||
</p>
|
||||
<div className="pt-4 border-t border-slate-800/80 flex items-center justify-between text-[11px] text-slate-400">
|
||||
<span className="font-mono text-emerald-400 font-semibold">100% Traceable</span>
|
||||
<span>Garage S3 Vault</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pillar 2 */}
|
||||
<div className="p-6 rounded-2xl bg-slate-900/60 border border-slate-800/80 hover:border-teal-500/40 transition-all shadow-xl group">
|
||||
<div className="w-12 h-12 rounded-xl bg-teal-500/10 border border-teal-500/20 flex items-center justify-center text-teal-400 mb-5 group-hover:scale-110 transition-transform">
|
||||
<MessageSquare className="w-6 h-6" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-xs font-mono font-semibold text-teal-400">PILLAR 02</span>
|
||||
<span className="text-slate-600">•</span>
|
||||
<span className="text-xs text-slate-400">Direct Comms</span>
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-white mb-2">
|
||||
Direct Programme Officer Comms
|
||||
</h3>
|
||||
<p className="text-xs text-slate-300 leading-relaxed mb-4">
|
||||
Eliminate lost email chains. Built-in contextual messaging links every query, revision request, and milestone note directly into an auditable project thread.
|
||||
</p>
|
||||
<div className="pt-4 border-t border-slate-800/80 flex items-center justify-between text-[11px] text-slate-400">
|
||||
<span className="font-mono text-teal-400 font-semibold">Direct Inbox</span>
|
||||
<span>Audit Logged</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pillar 3 */}
|
||||
<div className="p-6 rounded-2xl bg-slate-900/60 border border-slate-800/80 hover:border-cyan-500/40 transition-all shadow-xl group">
|
||||
<div className="w-12 h-12 rounded-xl bg-cyan-500/10 border border-cyan-500/20 flex items-center justify-center text-cyan-400 mb-5 group-hover:scale-110 transition-transform">
|
||||
<KeyRound className="w-6 h-6" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-xs font-mono font-semibold text-cyan-400">PILLAR 03</span>
|
||||
<span className="text-slate-600">•</span>
|
||||
<span className="text-xs text-slate-400">Rapid Mobilization</span>
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-white mb-2">
|
||||
Statutory SSO Onboarding & Tranches
|
||||
</h3>
|
||||
<p className="text-xs text-slate-300 leading-relaxed mb-4">
|
||||
Single-token statutory onboarding invitations allow instant portal mobilization, KYC compliance verification, and clear visibility into covenant-tied tranches.
|
||||
</p>
|
||||
<div className="pt-4 border-t border-slate-800/80 flex items-center justify-between text-[11px] text-slate-400">
|
||||
<span className="font-mono text-cyan-400 font-semibold">Zero Friction</span>
|
||||
<span>Duende STS Auth</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Screenshot Category Filter & Grid */}
|
||||
<div className="mb-6 flex flex-wrap items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-2 p-1 rounded-xl bg-slate-900 border border-slate-800">
|
||||
{categories.map((cat) => (
|
||||
<button
|
||||
key={cat}
|
||||
onClick={() => setSelectedCategory(cat)}
|
||||
className={`px-3 py-1.5 rounded-lg text-xs font-semibold transition-all ${
|
||||
selectedCategory === cat
|
||||
? 'bg-emerald-600 text-white shadow-sm'
|
||||
: 'text-slate-400 hover:text-slate-200'
|
||||
}`}
|
||||
>
|
||||
{cat}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<span className="text-xs text-slate-400 font-mono">
|
||||
Showing {filteredScreens.length} Partner Views
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Screenshot Cards Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{filteredScreens.map((screen) => (
|
||||
<div
|
||||
key={screen.id}
|
||||
onClick={() => onOpenScreenshot(screen)}
|
||||
className="group cursor-pointer rounded-2xl bg-slate-900/60 border border-slate-800 hover:border-emerald-500/50 overflow-hidden shadow-xl transition-all duration-300 hover:-translate-y-1"
|
||||
>
|
||||
<div className="relative aspect-[16/10] overflow-hidden bg-slate-950">
|
||||
<img
|
||||
src={screen.image}
|
||||
alt={screen.title}
|
||||
className="w-full h-full object-cover object-top group-hover:scale-105 transition-transform duration-500"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-slate-950 via-slate-950/20 to-transparent opacity-80 group-hover:opacity-40 transition-opacity" />
|
||||
<div className="absolute top-3 right-3 p-2 rounded-lg bg-slate-950/80 backdrop-blur-md border border-slate-700/80 text-slate-300 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<Maximize2 className="w-4 h-4" />
|
||||
</div>
|
||||
<div className="absolute bottom-3 left-3">
|
||||
<span className="text-[10px] uppercase font-bold tracking-wider px-2.5 py-1 rounded-full bg-emerald-500/20 text-emerald-300 border border-emerald-500/30 backdrop-blur-md">
|
||||
{screen.category}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-5">
|
||||
<h4 className="text-base font-bold text-white mb-1 group-hover:text-emerald-300 transition-colors">
|
||||
{screen.title}
|
||||
</h4>
|
||||
<p className="text-xs text-slate-300 leading-relaxed mb-4 line-clamp-2">
|
||||
{screen.description}
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{screen.tags.map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="text-[10px] font-mono px-2 py-0.5 rounded bg-slate-800/80 text-slate-400"
|
||||
>
|
||||
#{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user