IFIF Factory Administration System
A comprehensive smart contract factory management system for administering core protocol configurations, implementation upgrades, and infrastructure operations.
Overview
The IFIF Factory Administration System demonstrates how to build comprehensive factory analytics and management interfaces. It provides detailed analytics visualization, system metrics tracking, and secure administrative controls for factory configuration. The system integrates with progressive data loading for real-time factory deployment and system update monitoring.
Key Features
- Factory Analytics Dashboard: Comprehensive metrics grid with deployment counts, update frequency, and timeline charts
- Core Contract Management: Update whitelist, DEX router, and roles contracts with admin role validation
- Implementation Upgrades: Manage proxy implementation and token implementation contracts
- Base URI Configuration: Update NFT metadata base URI with administrative controls
- System Updates History: TanStack table with filtering, sorting, and pagination for configuration changes
- Real-time Configuration Display: Live display of current factory configuration values with loading states
- Administrative Security: Role-based access control with admin permission validation and connection checks
Smart Contract Integration
Core Contract Management
import { useState, useCallback, useMemo } from 'react'
import { useCachedFactoryData } from '@/lib/progressive-factory-hooks'
import { UpdateCoreModal } from '@/components/ifif-factory-modals'
import { useHasRole } from '@/lib/contract-hooks'
import { shortenAddress } from '@/config/constants'
import { Button } from '@/components/ui/button'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { GitBranch, AlertTriangle, Lock } from 'lucide-react'
import { useAccount } from 'wagmi'
import { Address, fromHex, Hex } from 'viem'
function CoreContractManager() {
const { address, isConnected } = useAccount()
const { systemUpdates, isSystemUpdatesLoading } = useCachedFactoryData()
// Extract current factory configuration values from latest system updates
const factoryConfig = useMemo(() => {
if (!systemUpdates || systemUpdates.length === 0) {
return {
implementation: null,
tokenImplementation: null,
whitelist: null,
dexRouter: null,
baseURI: null,
roles: null,
isLoading: isSystemUpdatesLoading
}
}
// Get the latest update for each update type
const latestByType: Record<number, string> = {}
// Sort by timestamp descending and get the most recent for each type
systemUpdates
.sort((a, b) => Number(b.timestamp) - Number(a.timestamp))
.forEach(update => {
if (!(update.updateType in latestByType)) {
latestByType[update.updateType] = update.newValue
}
})
return {
implementation: latestByType[0] || null, // Type 0: Implementation
tokenImplementation: latestByType[1] || null, // Type 1: Token Implementation
whitelist: latestByType[2] || null, // Type 2: Whitelist
dexRouter: latestByType[3] || null, // Type 3: DEX Router
baseURI: latestByType[4] && fromHex(latestByType[4] as Hex, "string") || null, // Type 4: Base URI
roles: latestByType[5] || null, // Type 5: Role Helper
isLoading: isSystemUpdatesLoading
}
}, [systemUpdates, isSystemUpdatesLoading])
const {
implementation,
tokenImplementation,
whitelist,
dexRouter,
baseURI,
roles,
isLoading: isLoadingFactoryValues
} = factoryConfig
// Check if user has admin role for management actions
const ADMIN_ROLE = '0xa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775'
const { hasRole: isAdmin, isLoading: isCheckingRole } = useHasRole(
ADMIN_ROLE,
isConnected ? address as Address : null
)
// Modal states for factory management
const [modals, setModals] = useState({
updateCore: false,
updateImplementation: false,
updateTokenImplementation: false,
updateBaseURI: false
})
// Modal handlers
const openModal = useCallback((modalName: keyof typeof modals) => {
setModals(prev => ({ ...prev, [modalName]: true }))
}, [])
const closeModal = useCallback((modalName: keyof typeof modals) => {
setModals(prev => ({ ...prev, [modalName]: false }))
}, [])
const handleManagementSuccess = useCallback(() => {
// With progressive hooks, data will automatically refresh when new system updates are indexed
// No manual refetch needed as the indexer will pick up the new events
console.log('Factory management operation completed successfully')
}, [])
return (
<div className="bg-white border border-slate-200 p-6 space-y-6">
<div>
<h3 className="text-lg font-semibold text-slate-900 mb-2">Core Contract Configuration</h3>
<p className="text-sm text-slate-600">
Update the core protocol contracts (whitelist, DEX router, roles)
</p>
</div>
{/* Current Values Display */}
<div className="bg-slate-50 p-4 rounded space-y-3">
<h4 className="font-medium">Current Configuration</h4>
<div className="grid grid-cols-1 gap-3 text-sm">
<div>
<span className="text-slate-600">Whitelist Contract:</span>
<div className="font-mono text-xs">
{whitelist ? shortenAddress(whitelist) : 'Not set'}
</div>
</div>
<div>
<span className="text-slate-600">DEX Router Contract:</span>
<div className="font-mono text-xs">
{dexRouter ? shortenAddress(dexRouter) : 'Not set'}
</div>
</div>
<div>
<span className="text-slate-600">Roles Contract:</span>
<div className="font-mono text-xs">
{roles ? shortenAddress(roles) : 'Not available from factory'}
</div>
</div>
</div>
</div>
{/* Admin Controls - Real Implementation Pattern */}
{!isConnected ? (
<Alert>
<AlertTriangle className="h-4 w-4" />
<AlertDescription>Please connect your wallet to access factory administration</AlertDescription>
</Alert>
) : !isAdmin ? (
<Alert>
<Lock className="h-4 w-4" />
<AlertDescription>
Admin role required to perform factory management operations.
{isCheckingRole ? ' Checking your permissions...' : ' Contact an administrator to request access.'}
</AlertDescription>
</Alert>
) : (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
<Button
variant="outline"
className="flex items-center gap-2 h-auto p-4 flex-col"
disabled={!isConnected || isLoadingFactoryValues}
onClick={() => openModal('updateCore')}
>
<GitBranch className="h-5 w-5" />
<div className="text-center">
<div className="font-medium">Update Core</div>
<div className="text-xs text-slate-600">Whitelist, DEX, Roles</div>
</div>
</Button>
</div>
)}
{/* Factory Management Modals - Real Implementation */}
<UpdateCoreModal
isOpen={modals.updateCore}
onClose={() => closeModal('updateCore')}
currentValues={{
whitelist: whitelist || undefined,
dexRouter: dexRouter || undefined,
roles: roles || undefined
}}
onSuccess={handleManagementSuccess}
/>
</div>
)
}Implementation Management
import { useState, useEffect } from 'react'
import {
useUpdateImplementation,
useUpdateTokenImplementation
} from '@/lib/ifif-factory-contract-hooks'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { AlertTriangle, CheckCircle } from 'lucide-react'
import { ExplorerLink } from '@/components/ui/explorer-link'
import { Address } from 'viem'
import { isAddress } from 'viem'
import { toast } from 'sonner'
function ImplementationManager() {
// Contract hook for updating implementation - Real pattern
const {
updateImplementation,
isLoading: isUpdatingImpl,
isSuccess: updateImplSuccess,
isError: updateImplError,
error: updateImplErrorMessage,
txHash: updateImplTxHash,
reset: resetImplUpdate
} = useUpdateImplementation()
// Contract hook for updating token implementation - Real pattern
const {
updateTokenImplementation,
isLoading: isUpdatingToken,
isSuccess: updateTokenSuccess,
isError: updateTokenError,
error: updateTokenErrorMessage,
txHash: updateTokenTxHash,
reset: resetTokenUpdate
} = useUpdateTokenImplementation()
const [newImplementation, setNewImplementation] = useState('')
const [newTokenImplementation, setNewTokenImplementation] = useState('')
// Handle implementation update success
useEffect(() => {
if (updateImplSuccess && updateImplTxHash) {
toast.success('Implementation updated successfully!')
setNewImplementation('')
setTimeout(() => {
resetImplUpdate()
}, 2000)
}
}, [updateImplSuccess, updateImplTxHash, resetImplUpdate])
// Handle token implementation update success
useEffect(() => {
if (updateTokenSuccess && updateTokenTxHash) {
toast.success('Token implementation updated successfully!')
setNewTokenImplementation('')
setTimeout(() => {
resetTokenUpdate()
}, 2000)
}
}, [updateTokenSuccess, updateTokenTxHash, resetTokenUpdate])
// Handle implementation update errors
useEffect(() => {
if (updateImplError && updateImplErrorMessage) {
toast.error(`Failed to update implementation: ${updateImplErrorMessage.message || 'Unknown error'}`)
}
}, [updateImplError, updateImplErrorMessage])
// Handle token implementation update errors
useEffect(() => {
if (updateTokenError && updateTokenErrorMessage) {
toast.error(`Failed to update token implementation: ${updateTokenErrorMessage.message || 'Unknown error'}`)
}
}, [updateTokenError, updateTokenErrorMessage])
const handleUpdateImplementation = async () => {
if (!isAddress(newImplementation)) {
toast.error('Please enter a valid implementation address')
return
}
try {
await updateImplementation({
newImplementation: newImplementation as Address
})
} catch (err) {
console.error('Failed to update implementation:', err)
}
}
const handleUpdateTokenImplementation = async () => {
if (!isAddress(newTokenImplementation)) {
toast.error('Please enter a valid token implementation address')
return
}
try {
await updateTokenImplementation({
newTokenImplementation: newTokenImplementation as Address
})
} catch (err) {
console.error('Failed to update token implementation:', err)
}
}
return (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* Project Implementation */}
<div className="bg-white border border-slate-200 p-6 space-y-4">
<div>
<h3 className="text-lg font-semibold text-slate-900 mb-2">Project Implementation</h3>
<p className="text-sm text-slate-600">
Manage the core project contract implementation
</p>
</div>
<div>
<Label htmlFor="newImplementation">New Implementation Address</Label>
<Input
id="newImplementation"
value={newImplementation}
onChange={(e) => setNewImplementation(e.target.value)}
placeholder="0x..."
/>
</div>
{updateImplError && updateImplErrorMessage && (
<Alert variant="destructive">
<AlertTriangle className="h-4 w-4" />
<AlertDescription>
{updateImplErrorMessage.message || 'Failed to update implementation'}
</AlertDescription>
</Alert>
)}
{updateImplSuccess && updateImplTxHash && (
<Alert>
<CheckCircle className="h-4 w-4" />
<AlertDescription className="space-y-2">
<p>Implementation updated successfully!</p>
<ExplorerLink type="tx" hash={updateImplTxHash}>
View Transaction
</ExplorerLink>
</AlertDescription>
</Alert>
)}
<Button
onClick={handleUpdateImplementation}
disabled={isUpdatingImpl || !newImplementation}
className="w-full"
>
{isUpdatingImpl ? 'Updating...' : 'Update Implementation'}
</Button>
</div>
{/* Token Implementation */}
<div className="bg-white border border-slate-200 p-6 space-y-4">
<div>
<h3 className="text-lg font-semibold text-slate-900 mb-2">Token Implementation</h3>
<p className="text-sm text-slate-600">
Manage the token contract implementation
</p>
</div>
<div>
<Label htmlFor="newTokenImplementation">New Token Implementation Address</Label>
<Input
id="newTokenImplementation"
value={newTokenImplementation}
onChange={(e) => setNewTokenImplementation(e.target.value)}
placeholder="0x..."
/>
</div>
{updateTokenError && updateTokenErrorMessage && (
<Alert variant="destructive">
<AlertTriangle className="h-4 w-4" />
<AlertDescription>
{updateTokenErrorMessage.message || 'Failed to update token implementation'}
</AlertDescription>
</Alert>
)}
{updateTokenSuccess && updateTokenTxHash && (
<Alert>
<CheckCircle className="h-4 w-4" />
<AlertDescription className="space-y-2">
<p>Token implementation updated successfully!</p>
<ExplorerLink type="tx" hash={updateTokenTxHash}>
View Transaction
</ExplorerLink>
</AlertDescription>
</Alert>
)}
<Button
onClick={handleUpdateTokenImplementation}
disabled={isUpdatingToken || !newTokenImplementation}
className="w-full"
>
{isUpdatingToken ? 'Updating...' : 'Update Token Implementation'}
</Button>
</div>
</div>
)
}Base URI Configuration
import { useState, useEffect } from 'react'
import { useUpdateBaseURI } from '@/lib/ifif-factory-contract-hooks'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import { AlertTriangle, CheckCircle } from 'lucide-react'
import { ExplorerLink } from '@/components/ui/explorer-link'
import { toast } from 'sonner'
function BaseURIManager() {
// Contract hook for updating base URI - Real pattern
const {
updateBaseURI,
isLoading: isUpdating,
isSuccess: updateSuccess,
isError: updateError,
error: updateErrorMessage,
txHash: updateTxHash,
reset: resetUpdate
} = useUpdateBaseURI()
const [newBaseURI, setNewBaseURI] = useState('')
// Validation logic matching real implementation
const validation = {
newBaseURI: newBaseURI.trim().length > 0,
isValidURI: newBaseURI.trim() ?
(newBaseURI.startsWith('http://') ||
newBaseURI.startsWith('https://') ||
newBaseURI.startsWith('ipfs://')) : true,
isValid: false
}
validation.isValid = validation.newBaseURI && validation.isValidURI
// Handle success - Real pattern
useEffect(() => {
if (updateSuccess && updateTxHash) {
toast.success('Base URI updated successfully!')
setNewBaseURI('')
setTimeout(() => {
resetUpdate()
}, 2000)
}
}, [updateSuccess, updateTxHash, resetUpdate])
// Handle errors - Real pattern
useEffect(() => {
if (updateError && updateErrorMessage) {
toast.error(`Failed to update base URI: ${updateErrorMessage.message || 'Unknown error'}`)
}
}, [updateError, updateErrorMessage])
const handleUpdateBaseURI = async () => {
if (!validation.isValid) {
if (!validation.newBaseURI) {
toast.error('Please enter a base URI')
return
}
if (!validation.isValidURI) {
toast.error('Please enter a valid URI (http://, https://, or ipfs://)')
return
}
}
try {
await updateBaseURI({
newBaseURI: newBaseURI.trim()
})
} catch (err) {
console.error('Failed to update base URI:', err)
}
}
return (
<div className="bg-white border border-slate-200 p-6 space-y-6">
<div>
<h3 className="text-lg font-semibold text-slate-900 mb-2">NFT Metadata Configuration</h3>
<p className="text-sm text-slate-600">
Configure the base URI for NFT metadata across all projects
</p>
</div>
<div>
<Label htmlFor="newBaseURI">New Base URI</Label>
<Input
id="newBaseURI"
value={newBaseURI}
onChange={(e) => setNewBaseURI(e.target.value)}
placeholder="https://api.yourproject.com/metadata/"
/>
<p className="text-xs text-slate-500 mt-1">
The base URI for NFT metadata. Token IDs will be appended to this URL.
</p>
{!validation.isValidURI && newBaseURI.trim() && (
<p className="text-xs text-red-500 mt-1">
URI must start with http://, https://, or ipfs://
</p>
)}
</div>
{updateError && updateErrorMessage && (
<Alert variant="destructive">
<AlertTriangle className="h-4 w-4" />
<AlertTitle>Update Failed</AlertTitle>
<AlertDescription>
{updateErrorMessage.message || 'Failed to update base URI'}
</AlertDescription>
</Alert>
)}
{updateSuccess && updateTxHash && (
<Alert>
<CheckCircle className="h-4 w-4" />
<AlertTitle>Update Successful</AlertTitle>
<AlertDescription className="space-y-2">
<p>Base URI has been updated successfully.</p>
<ExplorerLink type="tx" hash={updateTxHash}>
View Transaction
</ExplorerLink>
</AlertDescription>
</Alert>
)}
<div className="flex space-x-2">
<Button
onClick={handleUpdateBaseURI}
disabled={isUpdating || !validation.isValid}
className="flex-1"
>
{isUpdating ? 'Updating...' : 'Update Base URI'}
</Button>
<Button onClick={resetUpdate} variant="outline">
Reset
</Button>
</div>
</div>
)
}Data Layer Integration
Progressive Factory Data Loading
import { useCachedFactoryData } from '@/lib/progressive-factory-hooks'
import { shortenAddress } from '@/config/constants'
import { Factory } from 'lucide-react'
import { Badge } from '@/components/ui/badge'
// Real data structure interfaces from actual implementation
interface SystemUpdateEntry {
id: string
updateType: number
timestamp: string
newValue: string
blockNumber: string
}
interface FactoryDeploymentEntry {
id: string
projectId: number
projectAddress: string
projectName: string
projectSymbol: string
currentImplementation: string
timestamp: string
blockNumber: string
transactionHash: string
}
function FactoryAnalyticsDashboard() {
// Real useCachedFactoryData hook destructuring pattern - matches implementation exactly
const {
// Cached data - deployments are the factory projects
deployments: factoryDeployments,
systemUpdates,
projectLookup,
// Loading states
isDeploymentsLoading,
isSystemUpdatesLoading
} = useCachedFactoryData()
// Real system metrics calculation from implementation
const systemMetrics = useMemo(() => {
const totalDeployments = factoryDeployments.length
const totalUpdates = systemUpdates.length
// Calculate update frequency (updates per day in last 30 days)
const thirtyDaysAgo = Date.now() / 1000 - (30 * 24 * 3600)
const recentUpdates = systemUpdates.filter((u) => Number(u.timestamp) > thirtyDaysAgo)
const updateFrequency = recentUpdates.length / 30
return {
totalDeployments,
totalUpdates,
updateFrequency: Math.round(updateFrequency * 10) / 10
}
}, [factoryDeployments, systemUpdates])
// Overall loading state
const isLoading = isDeploymentsLoading || isSystemUpdatesLoading
// Real batch sizes from implementation
const BATCH_SIZES = {
DEPLOYMENTS: 15, // Real value from FACTORY_PROGRESSIVE_CONFIG
SYSTEM_UPDATES: 25 // Real value from FACTORY_PROGRESSIVE_CONFIG
}
return (
<div className="space-y-6">
<div className="bg-white border border-slate-200 p-6">
<div className="flex justify-between items-center mb-4">
<h3 className="text-lg font-semibold text-slate-900">Factory Statistics</h3>
<Badge variant="outline" className="text-slate-600">
{systemMetrics.totalDeployments} total deployments
</Badge>
</div>
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
<div className="text-center">
<div className="text-2xl font-bold text-blue-600">
{systemMetrics.totalDeployments}
</div>
<div className="text-sm text-slate-600">Factory Deployments</div>
</div>
<div className="text-center">
<div className="text-2xl font-bold text-green-600">
{systemMetrics.totalUpdates}
</div>
<div className="text-sm text-slate-600">System Updates</div>
</div>
<div className="text-center">
<div className="text-2xl font-bold text-purple-600">
{systemMetrics.updateFrequency}
</div>
<div className="text-sm text-slate-600">Updates/Day</div>
</div>
</div>
{/* Progressive loading indicator */}
{isLoading && (
<div className="mt-4 p-3 bg-blue-50 border border-blue-200 rounded">
<div className="text-sm text-blue-700">
Loading factory data progressively...
<div className="text-xs text-blue-600 mt-1">
Batch sizes: {BATCH_SIZES.DEPLOYMENTS} deployments, {BATCH_SIZES.SYSTEM_UPDATES} updates per request
</div>
</div>
</div>
)}
</div>
<div className="bg-white border border-slate-200 p-6">
<h3 className="text-lg font-semibold text-slate-900 mb-4">Recent Deployments</h3>
{isDeploymentsLoading ? (
<div className="space-y-3">
{[...Array(5)].map((_, i) => (
<div key={i} className="flex items-center space-x-4 p-3 border rounded animate-pulse">
<div className="w-12 h-12 bg-slate-300 rounded" />
<div className="flex-1 space-y-2">
<div className="h-4 bg-slate-300 w-1/3" />
<div className="h-3 bg-slate-200 w-1/2" />
</div>
<div className="h-6 bg-slate-300 w-20" />
</div>
))}
</div>
) : (
<div className="space-y-3">
{factoryDeployments.map((deployment) => (
<div key={deployment.id} className="flex items-center justify-between p-3 border rounded hover:bg-slate-50">
<div className="flex items-center space-x-3">
<div className="w-10 h-10 bg-blue-100 rounded flex items-center justify-center">
<Factory className="h-5 w-5 text-blue-600" />
</div>
<div>
<div className="font-medium">{deployment.projectName}</div>
<div className="text-sm text-slate-600">
Project #{deployment.projectId} • {deployment.projectSymbol}
</div>
<div className="text-xs text-slate-500 font-mono">
{shortenAddress(deployment.currentImplementation)}
</div>
</div>
</div>
<div className="text-right">
<Badge variant="outline">
{shortenAddress(deployment.projectAddress)}
</Badge>
<div className="text-xs text-slate-500 mt-1">
Block #{deployment.blockNumber}
</div>
</div>
</div>
))}
</div>
)}
{/* Project lookup functionality demo */}
<div className="mt-4 p-3 bg-slate-50 border rounded">
<div className="text-sm text-slate-600">
<strong>Project Lookup:</strong> {projectLookup.size} projects indexed
<div className="text-xs mt-1">
Lookup by project ID or address using: projectLookup.get(key)
</div>
</div>
</div>
</div>
</div>
)
}Factory Contract Monitoring
import { useCachedFactoryData } from '@/lib/progressive-factory-hooks'
import { useSettingsStore } from '@/lib/settings-store'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { AlertTriangle, Settings, Database, GitBranch, Activity, Lock } from 'lucide-react'
import { shortenAddress } from '@/config/constants'
import { fromHex, Hex } from 'viem'
import { useMemo } from 'react'
function FactoryStatusMonitor() {
const { isConnected } = useSettingsStore()
const { systemUpdates, isSystemUpdatesLoading } = useCachedFactoryData()
// Extract current factory configuration values from latest system updates
const factoryConfig = useMemo(() => {
if (!systemUpdates || systemUpdates.length === 0) {
return {
implementation: null,
tokenImplementation: null,
whitelist: null,
dexRouter: null,
baseURI: null,
roles: null,
isLoading: isSystemUpdatesLoading
}
}
// Get the latest update for each update type
const latestByType: Record<number, string> = {}
// Sort by timestamp descending and get the most recent for each type
systemUpdates
.sort((a, b) => Number(b.timestamp) - Number(a.timestamp))
.forEach(update => {
if (!(update.updateType in latestByType)) {
latestByType[update.updateType] = update.newValue
}
})
return {
implementation: latestByType[0] || null, // Type 0: Implementation
tokenImplementation: latestByType[1] || null, // Type 1: Token Implementation
whitelist: latestByType[2] || null, // Type 2: Whitelist
dexRouter: latestByType[3] || null, // Type 3: DEX Router
baseURI: latestByType[4] && fromHex(latestByType[4] as Hex, "string") || null, // Type 4: Base URI
roles: latestByType[5] || null, // Type 5: Role Helper
isLoading: isSystemUpdatesLoading
}
}, [systemUpdates, isSystemUpdatesLoading])
const {
implementation,
tokenImplementation,
whitelist,
dexRouter,
baseURI,
roles,
isLoading: isLoadingFactoryValues
} = factoryConfig
if (!isConnected) {
return (
<Alert>
<AlertTriangle className="h-4 w-4" />
<AlertDescription>
Connect to view and manage factory configuration
</AlertDescription>
</Alert>
)
}
const contractData = [
{
label: 'Implementation',
value: implementation,
icon: Settings,
status: implementation ? 'configured' : 'missing'
},
{
label: 'Token Implementation',
value: tokenImplementation,
icon: Activity,
status: tokenImplementation ? 'configured' : 'missing'
},
{
label: 'Whitelist',
value: whitelist,
icon: Lock,
status: whitelist ? 'configured' : 'missing'
},
{
label: 'DEX Router',
value: dexRouter,
icon: GitBranch,
status: dexRouter ? 'configured' : 'missing'
},
{
label: 'Roles',
value: roles,
icon: Database,
status: roles ? 'configured' : 'missing'
},
{
label: 'Base URI',
value: baseURI,
icon: Database,
status: baseURI ? 'configured' : 'missing'
}
]
return (
<div className="bg-white border border-slate-200 p-6 space-y-6">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold text-slate-900">Factory Configuration Status</h3>
<Badge variant="outline" className="text-slate-600">
Real-time from System Updates
</Badge>
</div>
<div className="mb-6">
<h4 className="text-sm font-medium text-slate-900 mb-3">Current Configuration</h4>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{contractData.map((item) => {
const IconComponent = item.icon
return (
<div key={item.label} className="bg-slate-50 p-4 rounded-lg">
<div className="flex items-center justify-between mb-2">
<div className="flex items-center space-x-2">
<IconComponent className="h-4 w-4 text-slate-600" />
<span className="text-sm font-medium text-slate-700">{item.label}</span>
</div>
{isLoadingFactoryValues && (
<div className="animate-spin rounded-full h-3 w-3 border-b border-slate-400"></div>
)}
</div>
<div className="flex items-center justify-between">
<p className="text-xs font-mono text-slate-600 break-all flex-1">
{item.value ?
(item.label === 'Base URI' ? item.value : shortenAddress(item.value))
: 'Not loaded'
}
</p>
<div className={`ml-2 w-2 h-2 rounded-full flex-shrink-0 ${
item.value ? 'bg-green-500' : 'bg-red-500'
}`} />
</div>
</div>
)
})}
</div>
</div>
{/* Configuration Summary */}
<div className="p-4 bg-blue-50 border border-blue-200 rounded-lg">
<div className="text-sm text-blue-700">
<strong>Configuration Source:</strong> Latest system update events from Factory contract
<div className="text-xs text-blue-600 mt-1">
Data refreshes automatically when new system updates are indexed by Ponder
</div>
</div>
</div>
</div>
)
}User Interface Patterns
Factory Administration Dashboard
import { useState, useMemo, useCallback } from 'react'
import {
UpdateCoreModal,
UpdateImplementationModal,
UpdateTokenImplementationModal,
UpdateBaseURIModal
} from '@/components/ifif-factory-modals'
import { useCachedFactoryData } from '@/lib/progressive-factory-hooks'
import { useSettingsStore } from '@/lib/settings-store'
import { useHasRole } from '@/lib/contract-hooks'
import { shortenAddress } from '@/config/constants'
import { Button } from '@/components/ui/button'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Badge } from '@/components/ui/badge'
import {
GitBranch,
Settings,
Activity,
Database,
Lock,
AlertTriangle,
Shield
} from 'lucide-react'
import { fromHex, Hex, Address } from 'viem'
import { useAccount } from 'wagmi'
function FactoryAdministrationDashboard() {
const { isConnected } = useSettingsStore()
const { address } = useAccount()
// Get cached data - using correct variable names from the hook
const {
systemUpdates,
isSystemUpdatesLoading
} = useCachedFactoryData()
// Extract current factory configuration values from latest system updates
const factoryConfig = useMemo(() => {
if (!systemUpdates || systemUpdates.length === 0) {
return {
implementation: null,
tokenImplementation: null,
whitelist: null,
dexRouter: null,
baseURI: null,
roles: null,
isLoading: isSystemUpdatesLoading
}
}
// Get the latest update for each update type
const latestByType: Record<number, string> = {}
// Sort by timestamp descending and get the most recent for each type
systemUpdates
.sort((a, b) => Number(b.timestamp) - Number(a.timestamp))
.forEach(update => {
if (!(update.updateType in latestByType)) {
latestByType[update.updateType] = update.newValue
}
})
return {
implementation: latestByType[0] || null, // Type 0: Implementation
tokenImplementation: latestByType[1] || null, // Type 1: Token Implementation
whitelist: latestByType[2] || null, // Type 2: Whitelist
dexRouter: latestByType[3] || null, // Type 3: DEX Router
baseURI: latestByType[4] && fromHex(latestByType[4] as Hex, "string") || null, // Type 4: Base URI
roles: latestByType[5] || null, // Type 5: Role Helper
isLoading: isSystemUpdatesLoading
}
}, [systemUpdates, isSystemUpdatesLoading])
const {
implementation,
tokenImplementation,
whitelist,
dexRouter,
baseURI,
roles,
isLoading: isLoadingFactoryValues
} = factoryConfig
// Check if user has admin role for management actions
const ADMIN_ROLE = '0xa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775'
const { hasRole: isAdmin, isLoading: isCheckingRole } = useHasRole(
ADMIN_ROLE,
address as Address
)
// Modal states for factory management - real pattern from implementation
const [modals, setModals] = useState({
updateCore: false,
updateImplementation: false,
updateTokenImplementation: false,
updateBaseURI: false
})
// Modal handlers - real pattern from implementation
const openModal = useCallback((modalName: keyof typeof modals) => {
setModals(prev => ({ ...prev, [modalName]: true }))
}, [])
const closeModal = useCallback((modalName: keyof typeof modals) => {
setModals(prev => ({ ...prev, [modalName]: false }))
}, [])
// Real success callback pattern from implementation
const handleManagementSuccess = useCallback(() => {
// With progressive hooks, data will automatically refresh when new system updates are indexed
// No manual refetch needed as the indexer will pick up the new events
console.log('Factory management operation completed successfully')
}, [])
return (
<div className="space-y-6">
{/* Management Actions - Real structure from factory analytics */}
<div className="bg-white border border-slate-200 space-y-6">
<div className="p-6 pb-0">
<div className="flex items-center justify-between">
<div>
<h3 className="text-lg font-semibold text-slate-900 flex items-center gap-2">
<Settings className="h-5 w-5" />
Factory Management
</h3>
<p className="text-sm text-slate-600 mt-1">
System-wide configuration and implementation updates
</p>
</div>
<div className="flex items-center gap-2">
{isCheckingRole ? (
<Badge variant="outline" className="text-slate-600">
Checking permissions...
</Badge>
) : isAdmin ? (
<Badge variant="default" className="bg-green-100 text-green-800 border-green-200">
<Shield className="h-3 w-3 mr-1" />
Admin Access
</Badge>
) : (
<Badge variant="outline" className="text-red-600 border-red-200">
<Lock className="h-3 w-3 mr-1" />
No Admin Access
</Badge>
)}
</div>
</div>
</div>
<div className="px-6 pb-6">
{!isConnected ? (
<Alert>
<AlertTriangle className="h-4 w-4" />
<AlertDescription>
Connect to view and manage factory configuration
</AlertDescription>
</Alert>
) : (
<>
{/* Current Configuration Display - Real pattern from implementation */}
<div className="mb-6">
<h4 className="text-sm font-medium text-slate-900 mb-3">Current Configuration</h4>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div className="bg-slate-50 p-4 rounded-lg">
<div className="flex items-center justify-between mb-2">
<span className="text-sm font-medium text-slate-700">Implementation</span>
{isLoadingFactoryValues && (
<div className="animate-spin rounded-full h-3 w-3 border-b border-slate-400"></div>
)}
</div>
<p className="text-xs font-mono text-slate-600 break-all">
{implementation ? shortenAddress(implementation) : 'Not loaded'}
</p>
</div>
<div className="bg-slate-50 p-4 rounded-lg">
<div className="flex items-center justify-between mb-2">
<span className="text-sm font-medium text-slate-700">Token Implementation</span>
{isLoadingFactoryValues && (
<div className="animate-spin rounded-full h-3 w-3 border-b border-slate-400"></div>
)}
</div>
<p className="text-xs font-mono text-slate-600 break-all">
{tokenImplementation ? shortenAddress(tokenImplementation) : 'Not loaded'}
</p>
</div>
<div className="bg-slate-50 p-4 rounded-lg">
<div className="flex items-center justify-between mb-2">
<span className="text-sm font-medium text-slate-700">Whitelist</span>
{isLoadingFactoryValues && (
<div className="animate-spin rounded-full h-3 w-3 border-b border-slate-400"></div>
)}
</div>
<p className="text-xs font-mono text-slate-600 break-all">
{whitelist ? shortenAddress(whitelist) : 'Not loaded'}
</p>
</div>
<div className="bg-slate-50 p-4 rounded-lg">
<div className="flex items-center justify-between mb-2">
<span className="text-sm font-medium text-slate-700">DEX Router</span>
{isLoadingFactoryValues && (
<div className="animate-spin rounded-full h-3 w-3 border-b border-slate-400"></div>
)}
</div>
<p className="text-xs font-mono text-slate-600 break-all">
{dexRouter ? shortenAddress(dexRouter) : 'Not loaded'}
</p>
</div>
<div className="bg-slate-50 p-4 rounded-lg">
<div className="flex items-center justify-between mb-2">
<span className="text-sm font-medium text-slate-700">Roles</span>
{isLoadingFactoryValues && (
<div className="animate-spin rounded-full h-3 w-3 border-b border-slate-400"></div>
)}
</div>
<p className="text-xs font-mono text-slate-600 break-all">
{roles ? shortenAddress(roles) : 'Not loaded'}
</p>
</div>
<div className="bg-slate-50 p-4 rounded-lg">
<div className="flex items-center justify-between mb-2">
<span className="text-sm font-medium text-slate-700">Base URI</span>
{isLoadingFactoryValues && (
<div className="animate-spin rounded-full h-3 w-3 border-b border-slate-400"></div>
)}
</div>
<p className="text-xs text-slate-600 break-all">
{baseURI || 'Not set'}
</p>
</div>
</div>
</div>
{/* Management Actions - Real button grid layout from implementation */}
<div>
<h4 className="text-sm font-medium text-slate-900 mb-3">Management Actions</h4>
{!isAdmin ? (
<Alert>
<Lock className="h-4 w-4" />
<AlertDescription>
Admin role required to perform factory management operations.
{isCheckingRole ? ' Checking your permissions...' : ' Contact an administrator to request access.'}
</AlertDescription>
</Alert>
) : (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
<Button
variant="outline"
className="flex items-center gap-2 h-auto p-4 flex-col"
disabled={!isConnected || isLoadingFactoryValues}
onClick={() => openModal('updateCore')}
>
<GitBranch className="h-5 w-5" />
<div className="text-center">
<div className="font-medium">Update Core</div>
<div className="text-xs text-slate-600">Whitelist, DEX, Roles</div>
</div>
</Button>
<Button
variant="outline"
className="flex items-center gap-2 h-auto p-4 flex-col"
disabled={!isConnected || isLoadingFactoryValues}
onClick={() => openModal('updateImplementation')}
>
<Settings className="h-5 w-5" />
<div className="text-center">
<div className="font-medium">Update Implementation</div>
<div className="text-xs text-slate-600">Project contract</div>
</div>
</Button>
<Button
variant="outline"
className="flex items-center gap-2 h-auto p-4 flex-col"
disabled={!isConnected || isLoadingFactoryValues}
onClick={() => openModal('updateTokenImplementation')}
>
<Activity className="h-5 w-5" />
<div className="text-center">
<div className="font-medium">Update Token Impl</div>
<div className="text-xs text-slate-600">Token contract</div>
</div>
</Button>
<Button
variant="outline"
className="flex items-center gap-2 h-auto p-4 flex-col"
disabled={!isConnected || isLoadingFactoryValues}
onClick={() => openModal('updateBaseURI')}
>
<Database className="h-5 w-5" />
<div className="text-center">
<div className="font-medium">Update Base URI</div>
<div className="text-xs text-slate-600">NFT metadata</div>
</div>
</Button>
</div>
)}
</div>
</>
)}
</div>
</div>
{/* Factory Management Modals - Real modal component props from implementation */}
<UpdateCoreModal
isOpen={modals.updateCore}
onClose={() => closeModal('updateCore')}
currentValues={{
whitelist: whitelist || undefined,
dexRouter: dexRouter || undefined,
roles: roles || undefined
}}
onSuccess={handleManagementSuccess}
/>
<UpdateImplementationModal
isOpen={modals.updateImplementation}
onClose={() => closeModal('updateImplementation')}
currentImplementation={implementation || undefined}
onSuccess={handleManagementSuccess}
/>
<UpdateTokenImplementationModal
isOpen={modals.updateTokenImplementation}
onClose={() => closeModal('updateTokenImplementation')}
currentTokenImplementation={tokenImplementation || undefined}
onSuccess={handleManagementSuccess}
/>
<UpdateBaseURIModal
isOpen={modals.updateBaseURI}
onClose={() => closeModal('updateBaseURI')}
currentBaseURI={baseURI || undefined}
onSuccess={handleManagementSuccess}
/>
</div>
)
}Error Handling
Factory Operation Error Management
import { useState, useEffect } from 'react'
import { useUpdateCore } from '@/lib/ifif-factory-contract-hooks'
import { TransactionInfo, TransactionButton } from '@/components/ui/transaction-info'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { CopyButton } from '@/components/ui/copy-button'
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog'
import { GitBranch, AlertTriangle } from 'lucide-react'
import { Address, isAddress } from 'viem'
import { shortenAddress } from '@/config/constants'
function FactoryOperationWithErrorHandling() {
const [formData, setFormData] = useState({
whitelist: '',
dexRouter: '',
roles: ''
})
const [isHydrated, setIsHydrated] = useState(false)
useEffect(() => {
setIsHydrated(true)
}, [])
// Real hook destructuring pattern from implementation - no property renaming
const {
updateCore,
isLoading,
isSuccess,
isError,
error,
txHash,
reset
} = useUpdateCore()
// Real validation pattern from modals
const validation = {
whitelist: formData.whitelist.trim() ? isAddress(formData.whitelist) : false,
dexRouter: formData.dexRouter.trim() ? isAddress(formData.dexRouter) : false,
roles: formData.roles.trim() ? isAddress(formData.roles) : false,
isValid: false
}
validation.isValid = validation.whitelist && validation.dexRouter && validation.roles
// Real success handling pattern from modals
useEffect(() => {
if (isSuccess && txHash) {
// Auto-close/reset pattern from real modals
setTimeout(() => {
reset()
setFormData({ whitelist: '', dexRouter: '', roles: '' })
}, 2000)
}
}, [isSuccess, txHash, reset])
// Real form submission pattern from modals
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!validation.isValid) return
try {
await updateCore({
whitelist: formData.whitelist as Address,
dexRouter: formData.dexRouter as Address,
roles: formData.roles as Address
})
} catch (error) {
// Error state is managed by the hook automatically
console.error('Failed to update core:', error)
}
}
// Real close/reset pattern from modals
const handleClose = () => {
if (!isLoading) {
reset()
setFormData({ whitelist: '', dexRouter: '', roles: '' })
}
}
if (!isHydrated) return null
return (
<Dialog open={true} onOpenChange={handleClose}>
<DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<GitBranch className="h-5 w-5" />
Update Core Contracts
</DialogTitle>
<DialogDescription>
Update the core system contracts (whitelist, DEX router, and roles).
This affects all factory operations system-wide.
</DialogDescription>
</DialogHeader>
<form onSubmit={handleSubmit} className="space-y-6">
{/* Whitelist Address - Real pattern from modals */}
<div className="space-y-2">
<Label htmlFor="whitelist">Whitelist Contract Address</Label>
<div className="space-y-2">
<Input
id="whitelist"
placeholder="0x..."
value={formData.whitelist}
onChange={(e) => setFormData(prev => ({ ...prev, whitelist: e.target.value }))}
className={`font-mono ${
formData.whitelist && !validation.whitelist ? 'border-red-300' : ''
}`}
/>
{formData.whitelist && !validation.whitelist && (
<p className="text-sm text-red-600">Please enter a valid contract address</p>
)}
</div>
</div>
{/* DEX Router Address */}
<div className="space-y-2">
<Label htmlFor="dexRouter">DEX Router Contract Address</Label>
<div className="space-y-2">
<Input
id="dexRouter"
placeholder="0x..."
value={formData.dexRouter}
onChange={(e) => setFormData(prev => ({ ...prev, dexRouter: e.target.value }))}
className={`font-mono ${
formData.dexRouter && !validation.dexRouter ? 'border-red-300' : ''
}`}
/>
{formData.dexRouter && !validation.dexRouter && (
<p className="text-sm text-red-600">Please enter a valid contract address</p>
)}
</div>
</div>
{/* Roles Address */}
<div className="space-y-2">
<Label htmlFor="roles">Roles Contract Address</Label>
<div className="space-y-2">
<Input
id="roles"
placeholder="0x..."
value={formData.roles}
onChange={(e) => setFormData(prev => ({ ...prev, roles: e.target.value }))}
className={`font-mono ${
formData.roles && !validation.roles ? 'border-red-300' : ''
}`}
/>
{formData.roles && !validation.roles && (
<p className="text-sm text-red-600">Please enter a valid contract address</p>
)}
</div>
</div>
{/* Warning Alert - Real pattern from modals */}
<Alert>
<AlertTriangle className="h-4 w-4" />
<AlertDescription>
<strong>Warning:</strong> Updating core contracts affects the entire factory system.
Ensure the new contracts are properly deployed and tested.
</AlertDescription>
</Alert>
{/* Transaction Status - Real TransactionInfo component usage */}
<TransactionInfo
isLoading={isLoading}
isSuccess={isSuccess && !!txHash}
isError={isError}
error={error}
txHash={txHash}
loadingText="Updating core contracts..."
successText="Core contracts updated successfully!"
/>
{/* Actions - Real button pattern from modals */}
<div className="flex items-center justify-end space-x-3 pt-4 border-t">
<Button
type="button"
variant="outline"
onClick={handleClose}
disabled={isLoading}
>
{isSuccess ? 'Close' : 'Cancel'}
</Button>
<TransactionButton
type="submit"
disabled={!validation.isValid || isLoading}
isLoading={isLoading}
isSuccess={isSuccess}
defaultText="Update Core"
loadingText="Updating..."
successText="Updated!"
className="min-w-[120px]"
/>
</div>
</form>
</DialogContent>
</Dialog>
)
}Real Error Handling Patterns
import { useState, useCallback } from 'react'
import { useUpdateImplementation } from '@/lib/ifif-factory-contract-hooks'
import { TransactionInfo } from '@/components/ui/transaction-info'
import { Button } from '@/components/ui/button'
import { Address } from 'viem'
// Real error state management from factory hooks
interface FactoryOperationState {
isLoading: boolean
isSuccess: boolean
isError: boolean
error: string | null
txHash: string | null
}
function FactoryErrorHandlingExample() {
// Real hook usage - no property renaming, returns state directly
const {
updateImplementation,
isLoading,
isSuccess,
isError,
error,
txHash,
reset
} = useUpdateImplementation()
// Real error handling from hooks implementation
const handleOperation = useCallback(async (newImplementation: Address) => {
try {
// Hook manages state internally
await updateImplementation({ newImplementation })
} catch (error) {
// Error is already captured by the hook's internal error handling
console.error('Failed to update implementation:', error)
// Error details are available in the hook's error state:
// - isError: boolean (true when operation fails)
// - error: string | null (actual error message)
// - Hook automatically sets isLoading: false and isSuccess: false
}
}, [updateImplementation])
// Real reset pattern from modals
const handleReset = useCallback(() => {
reset() // Resets all state: isLoading, isSuccess, isError, error, txHash
}, [reset])
return (
<div className="space-y-4">
{/* Real TransactionInfo component handles all states including Explorer links */}
<TransactionInfo
isLoading={isLoading}
isSuccess={isSuccess && !!txHash}
isError={isError}
error={error} // Real error message from contract/transaction
txHash={txHash}
loadingText="Processing factory operation..."
successText="Factory operation completed successfully!"
/>
{/* Manual reset for retry functionality */}
{(isError || isSuccess) && (
<div className="flex justify-end">
<Button
variant="outline"
size="sm"
onClick={handleReset}
>
{isError ? 'Try Again' : 'Reset'}
</Button>
</div>
)}
</div>
)
}Success State with Explorer Links
import { useMemo } from 'react'
import { CopyButton } from '@/components/ui/copy-button'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { CheckCircle2, ExternalLink, Clock } from 'lucide-react'
import { useAccount } from 'wagmi'
import Link from 'next/link'
// Real success display pattern from TransactionInfo component
function FactorySuccessState({ txHash }: { txHash: string }) {
const { chain } = useAccount()
// Real explorer URL construction from TransactionInfo
const txExplorerUrl = useMemo(() => {
const explorerUrl = chain?.blockExplorers?.default?.url
return explorerUrl && txHash
? `${explorerUrl}/tx/${txHash}`
: null
}, [chain?.blockExplorers?.default?.url, txHash])
return (
<div className="p-4 bg-green-50 border border-green-200 rounded-lg">
<div className="flex items-start gap-3">
<CheckCircle2 className="h-5 w-5 text-green-600 mt-0.5" />
<div className="flex-1 space-y-2">
<p className="text-sm font-medium text-green-900">
Factory operation completed successfully!
</p>
<div className="space-y-2">
<div className="flex items-center gap-2">
<Badge variant="outline" className="text-xs bg-green-100 text-green-800 border-green-300">
<Clock className="h-3 w-3 mr-1" />
Submitted
</Badge>
</div>
{/* Real transaction display with Explorer link */}
<div className="bg-white/60 border border-green-200 rounded p-3">
<div className="flex items-center justify-between mb-2">
<span className="text-xs font-medium text-green-800">Transaction Hash</span>
<div className="flex items-center gap-1">
<CopyButton
text={txHash}
size="sm"
variant="outline"
className="h-6 text-xs"
/>
{txExplorerUrl ? (
<Link href={txExplorerUrl} target="_blank" rel="noopener noreferrer">
<Button
size="sm"
variant="outline"
className="h-6 text-xs"
>
<ExternalLink className="h-3 w-3 mr-1" />
Explorer
</Button>
</Link>
) : (
<Button
size="sm"
variant="outline"
className="h-6 text-xs"
disabled
title="Explorer not available for this network"
>
<ExternalLink className="h-3 w-3 mr-1" />
Explorer
</Button>
)}
</div>
</div>
<code className="text-xs font-mono text-green-700 break-all">
{txHash}
</code>
</div>
</div>
</div>
</div>
</div>
)
}Input Validation Patterns
import { useState } from 'react'
import { isAddress, Address } from 'viem'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { FACTORY_UPDATE_TYPES, shortenAddress } from '@/config/constants'
// Real validation patterns from UpdateCoreModal implementation
function CoreContractValidationExample() {
const [formData, setFormData] = useState({
whitelist: '',
dexRouter: '',
roles: ''
})
// Real validation logic from UpdateCoreModal
const validation = {
whitelist: formData.whitelist.trim() ? isAddress(formData.whitelist) : false,
dexRouter: formData.dexRouter.trim() ? isAddress(formData.dexRouter) : false,
roles: formData.roles.trim() ? isAddress(formData.roles) : false,
isValid: false
}
validation.isValid = validation.whitelist && validation.dexRouter && validation.roles
return (
<div className="space-y-4">
{/* Whitelist Contract - Real pattern from UpdateCoreModal */}
<div className="space-y-2">
<Label htmlFor="whitelist">Whitelist Contract</Label>
<Input
id="whitelist"
placeholder="0x..."
value={formData.whitelist}
onChange={(e) => setFormData(prev => ({ ...prev, whitelist: e.target.value }))}
className={
formData.whitelist && !validation.whitelist ? 'border-red-300' : ''
}
/>
{formData.whitelist && !validation.whitelist && (
<p className="text-sm text-red-600">Please enter a valid contract address</p>
)}
</div>
{/* DEX Router Contract */}
<div className="space-y-2">
<Label htmlFor="dexRouter">DEX Router Contract</Label>
<Input
id="dexRouter"
placeholder="0x..."
value={formData.dexRouter}
onChange={(e) => setFormData(prev => ({ ...prev, dexRouter: e.target.value }))}
className={
formData.dexRouter && !validation.dexRouter ? 'border-red-300' : ''
}
/>
{formData.dexRouter && !validation.dexRouter && (
<p className="text-sm text-red-600">Please enter a valid contract address</p>
)}
</div>
{/* Roles Contract */}
<div className="space-y-2">
<Label htmlFor="roles">Roles Contract</Label>
<Input
id="roles"
placeholder="0x..."
value={formData.roles}
onChange={(e) => setFormData(prev => ({ ...prev, roles: e.target.value }))}
className={
formData.roles && !validation.roles ? 'border-red-300' : ''
}
/>
{formData.roles && !validation.roles && (
<p className="text-sm text-red-600">Please enter a valid contract address</p>
)}
</div>
<Button disabled={!validation.isValid}>
Update Core Contracts
</Button>
</div>
)
}
// Real Implementation validation from UpdateImplementationModal
function ImplementationValidationExample() {
const [formData, setFormData] = useState({ newImplementation: '' })
// Real validation logic from UpdateImplementationModal
const validation = {
newImplementation: formData.newImplementation.trim() ? isAddress(formData.newImplementation) : false,
isValid: false
}
validation.isValid = validation.newImplementation
return (
<div className="space-y-4">
<div className="space-y-2">
<Label htmlFor="newImplementation">New Implementation Contract</Label>
<Input
id="newImplementation"
placeholder="0x..."
value={formData.newImplementation}
onChange={(e) => setFormData(prev => ({ ...prev, newImplementation: e.target.value }))}
className={
formData.newImplementation && !validation.newImplementation ? 'border-red-300' : ''
}
/>
{formData.newImplementation && !validation.newImplementation && (
<p className="text-sm text-red-600">Please enter a valid contract address</p>
)}
</div>
<Button disabled={!validation.isValid}>
Update Implementation
</Button>
</div>
)
}
function BaseURIValidationExample() {
const [formData, setFormData] = useState({ newBaseURI: '' })
// Real validation logic from UpdateBaseURIModal
const validation = {
newBaseURI: formData.newBaseURI.trim().length > 0,
isValidURI: formData.newBaseURI.trim() ?
(formData.newBaseURI.startsWith('http://') ||
formData.newBaseURI.startsWith('https://') ||
formData.newBaseURI.startsWith('ipfs://')) : true,
isValid: false
}
validation.isValid = validation.newBaseURI && validation.isValidURI
return (
<div className="space-y-4">
<div className="space-y-2">
<Label htmlFor="baseURI">Base URI</Label>
<Input
id="baseURI"
placeholder="https://api.example.com/metadata/"
value={formData.newBaseURI}
onChange={(e) => setFormData(prev => ({ ...prev, newBaseURI: e.target.value }))}
className={
formData.newBaseURI && !validation.isValidURI ? 'border-red-300' : ''
}
/>
{formData.newBaseURI && !validation.isValidURI && (
<p className="text-sm text-red-600">
Please enter a valid URI (http://, https://, or ipfs://)
</p>
)}
</div>
<Button disabled={!validation.isValid}>
Update Base URI
</Button>
</div>
)
}
)
}
// Additional Implementation Examples - Token Implementation validation
function TokenImplementationValidationExample() {
const [formData, setFormData] = useState({ newTokenImplementation: '' })
// Real validation logic from UpdateTokenImplementationModal
const validation = {
newTokenImplementation: formData.newTokenImplementation.trim() ? isAddress(formData.newTokenImplementation) : false,
isValid: false
}
validation.isValid = validation.newTokenImplementation
return (
<div className="space-y-4">
<div className="space-y-2">
<Label htmlFor="newTokenImplementation">New Token Implementation Contract</Label>
<Input
id="newTokenImplementation"
placeholder="0x..."
value={formData.newTokenImplementation}
onChange={(e) => setFormData(prev => ({ ...prev, newTokenImplementation: e.target.value }))}
className={
formData.newTokenImplementation && !validation.newTokenImplementation ? 'border-red-300' : ''
}
/>
{formData.newTokenImplementation && !validation.newTokenImplementation && (
<p className="text-sm text-red-600">Please enter a valid contract address</p>
)}
</div>
<Button disabled={!validation.isValid}>
Update Token Implementation
</Button>
</div>
)
}
function UpdateTypeIndicators() {
const updateTypes = [
{ key: '0', type: { name: 'Implementation', color: 'bg-blue-500', description: 'Project implementation contract updated' }},
{ key: '1', type: { name: 'Token Implementation', color: 'bg-green-500', description: 'Token implementation contract updated' }},
{ key: '2', type: { name: 'Whitelist', color: 'bg-purple-500', description: 'Whitelist contract updated' }},
{ key: '3', type: { name: 'DEX Router', color: 'bg-orange-500', description: 'DEX router contract updated' }},
{ key: '4', type: { name: 'Base URI', color: 'bg-cyan-500', description: 'Base URI updated' }},
{ key: '5', type: { name: 'Role Helper', color: 'bg-pink-500', description: 'Role helper updated' }}
]
return (
<div className="space-y-3">
<h4 className="font-medium text-slate-900">Factory Update Types</h4>
<div className="grid grid-cols-2 gap-3">
{updateTypes.map(({ key, type }) => (
<div key={key} className="p-3 bg-slate-50 rounded-lg">
<div className="flex items-center gap-2 mb-1">
<div className={`w-3 h-3 rounded-full ${type.color}`} />
<span className="font-medium text-sm">{type.name}</span>
</div>
<p className="text-xs text-slate-600">{type.description}</p>
<code className="text-xs bg-slate-100 px-1 rounded">Type {key}</code>
</div>
))}
</div>
</div>
)
}Transaction State Management
import { useEffect } from 'react'
import { TransactionInfo } from '@/components/ui/transaction-info'
import { Button } from '@/components/ui/button'
// Real transaction lifecycle management from modals
function FactoryTransactionManager({ onSuccess }: { onSuccess?: () => void }) {
const {
updateCore,
isLoading: isUpdating,
isSuccess: updateSuccess,
isError: updateError,
error: updateErrorMessage,
txHash: updateTxHash,
reset: resetUpdate
} = useUpdateCore()
// Real success handling pattern from modals
useEffect(() => {
if (updateSuccess && updateTxHash) {
// Close modal or show success state
onSuccess?.()
// Auto-reset after delay
const timer = setTimeout(() => {
resetUpdate()
}, 2000)
return () => clearTimeout(timer)
}
}, [updateSuccess, updateTxHash, resetUpdate, onSuccess])
// Real error display using TransactionInfo component
return (
<div className="space-y-4">
{/* Transaction status display */}
<TransactionInfo
isLoading={isUpdating}
isSuccess={updateSuccess && !!updateTxHash}
isError={updateError}
error={updateErrorMessage}
txHash={updateTxHash}
loadingText="Processing factory operation..."
successText="Factory operation completed successfully!"
/>
{/* Manual reset option */}
{(updateError || updateSuccess) && (
<div className="flex justify-end">
<Button
variant="outline"
size="sm"
onClick={resetUpdate}
>
{updateError ? 'Try Again' : 'Reset'}
</Button>
</div>
)}
</div>
)
}Constants
Factory Configuration Constants
// Real progressive loading configuration from progressive-factory-hooks.ts
const FACTORY_PROGRESSIVE_CONFIG = {
deployments: {
batchSize: 15, // Real value from progressive-factory-hooks.ts
},
systemUpdates: {
batchSize: 25, // Real value from progressive-factory-hooks.ts
}
}
// Real analytics progressive config from config/constants.ts
export const ANALYTICS_PROGRESSIVE_CONFIG = {
dailyMetrics: {
batchSize: 30, // Load 30 days at a time
defaultDays: 30,
maxDays: 365, // Maximum days to load at once
},
summaryAnalytics: {
refreshInterval: 300, // 5 minutes in seconds
cacheTimeout: 900, // 15 minutes in seconds
},
trendsAnalysis: {
defaultWindow: 7, // Default moving average window
maxWindow: 30, // Maximum window size
},
performance: {
debounceMs: 300, // Debounce filter changes
maxConcurrentQueries: 3, // Limit concurrent queries
}
}
// Real factory update types from config/constants.ts
export const FACTORY_UPDATE_TYPES: Record<number, { name: string; color: string; description: string }> = {
0: {
name: 'Implementation',
color: 'bg-blue-500',
description: 'Project implementation contract updated'
},
1: {
name: 'Token Implementation',
color: 'bg-green-500',
description: 'Token implementation contract updated'
},
2: {
name: 'Whitelist',
color: 'bg-purple-500',
description: 'Whitelist contract updated'
},
3: {
name: 'DEX Router',
color: 'bg-orange-500',
description: 'DEX router contract updated'
},
4: {
name: 'Base URI',
color: 'bg-cyan-500',
description: 'Base URI updated'
},
5: {
name: 'Role Helper',
color: 'bg-pink-500',
description: 'Role helper updated'
}
}
// Real role constants from config/constants.ts
export const ROLE_NAMES: Record<string, { name: string; color: string; description: string }> = {
'0x0000000000000000000000000000000000000000000000000000000000000000': {
name: 'Default Admin',
color: 'bg-red-500',
description: 'Super administrator with all permissions'
},
'0xa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775': {
name: 'Admin',
color: 'bg-blue-500',
description: 'Administrative permissions'
},
'0x241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08': {
name: 'Manager',
color: 'bg-green-500',
description: 'Management and operational permissions'
},
'0xfbd454f36a7e1a388bd6fc3ab10d434aa4578f811acbbcf33afb1c697486313c': {
name: 'Distributor',
color: 'bg-purple-500',
description: 'Distribution and allocation permissions'
}
}
// Real utility functions from config/constants.ts
export const shortenAddress = (address: string) => `${address.slice(0, 6)}...${address.slice(-4)}`
export const shortenHash = (role: string) => `${role.slice(0, 10)}...${role.slice(-8)}`Security and Performance
Administrative Security Controls
import { useAccount } from 'wagmi'
import { useHasRole } from '@/lib/contract-hooks'
import { useSettingsStore } from '@/lib/settings-store'
import { Shield, Lock, AlertTriangle, Settings, GitBranch } from 'lucide-react'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Address } from 'viem'
// Real admin security implementation from factory-analytics page
function FactoryManagementSection() {
const { isConnected: walletConnected, address } = useAccount()
const { isConnected } = useSettingsStore()
// Real admin role hash from constants
const ADMIN_ROLE = '0xa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775'
// Real useHasRole pattern from factory-analytics implementation
const { hasRole: isAdmin, isLoading: isCheckingRole } = useHasRole(
ADMIN_ROLE,
walletConnected ? address as Address : null
)
return (
<div className="bg-white border border-slate-200 space-y-6">
<div className="p-6 pb-0">
<div className="flex items-center justify-between">
<div>
<h3 className="text-lg font-semibold text-slate-900 flex items-center gap-2">
<Settings className="h-5 w-5" />
Factory Management
</h3>
<p className="text-sm text-slate-600 mt-1">
System-wide configuration and implementation updates
</p>
</div>
{/* Real permission checking badges from factory-analytics */}
<div className="flex items-center gap-2">
{isCheckingRole ? (
<Badge variant="outline" className="text-slate-600">
Checking permissions...
</Badge>
) : isAdmin ? (
<Badge variant="default" className="bg-green-100 text-green-800 border-green-200">
<Shield className="h-3 w-3 mr-1" />
Admin Access
</Badge>
) : (
<Badge variant="outline" className="text-red-600 border-red-200">
<Lock className="h-3 w-3 mr-1" />
No Admin Access
</Badge>
)}
</div>
</div>
</div>
<div className="px-6 pb-6">
{/* Real connection check from factory-analytics */}
{!isConnected ? (
<Alert>
<AlertTriangle className="h-4 w-4" />
<AlertDescription>
Connect to view and manage factory configuration
</AlertDescription>
</Alert>
) : (
<>
{/* Current Configuration Display would go here */}
{/* Real admin permission check from factory-analytics */}
{!isAdmin ? (
<Alert>
<Lock className="h-4 w-4" />
<AlertDescription>
Admin role required to perform factory management operations.
{isCheckingRole ? ' Checking your permissions...' : ' Contact an administrator to request access.'}
</AlertDescription>
</Alert>
) : (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
{/* Real management action buttons from factory-analytics */}
<Button
variant="outline"
className="flex items-center gap-2 h-auto p-4 flex-col"
disabled={!isConnected || isCheckingRole}
onClick={() => console.log('Update Core')}
>
<GitBranch className="h-5 w-5" />
<div className="text-center">
<div className="font-medium">Update Core</div>
<div className="text-xs text-slate-600">Whitelist, DEX, Roles</div>
</div>
</Button>
<Button
variant="outline"
className="flex items-center gap-2 h-auto p-4 flex-col"
disabled={!isConnected || isCheckingRole}
onClick={() => console.log('Update Implementation')}
>
<Settings className="h-5 w-5" />
<div className="text-center">
<div className="font-medium">Update Implementation</div>
<div className="text-xs text-slate-600">Project contract</div>
</div>
</Button>
</div>
)}
</>
)}
</div>
</div>
)
}The IFIF Factory Administration System provides a comprehensive foundation for managing complex smart contract factory operations with enterprise-grade security, monitoring, and administrative controls.