Skip to content

Commit bfa539f

Browse files
refactor: align company registration workflow with single-admin logic
- Updated `Companies` page: removed the "Create Proposal" button for pending registrations to prevent confusion. - Added clear UI instructions to use the "CRSet Admins" tool to finalize onboarding, matching the system's operational architecture. - Updated README.md usage guide to reflect the direct admin addition workflow instead of governance proposals. - Fixed unused variable linting error in `Companies.tsx`.
1 parent 514fa29 commit bfa539f

2 files changed

Lines changed: 91 additions & 67 deletions

File tree

packages/demo-app-frontend/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ The application supports two distinct user roles. Use MetaMask to switch between
8686
* Go to **Companies**.
8787
* Search for a company's DID address (Wallet Address).
8888
* If the company is "Not Managed", wait for them to delegate control.
89-
* If they have delegated, click **"Register Company"** to create a governance proposal.
90-
* **Admin Tools:** Use the "CRSet Admins" panel to add the company's wallet as an admin for their specific CRSet.
89+
* If they have delegated (Yellow status), scroll down to **"CRSet Admins"**.
90+
* Paste the company's address and click **Add**. This completes the registration immediately (no proposal required).
9191

9292

9393
3. **Governance:**

packages/demo-app-frontend/src/pages/trust-anchor/Companies.tsx

Lines changed: 89 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
1-
import { Plus, Loader2, CheckCircle2, AlertTriangle, Search, Building2, UserPlus, UserMinus, RefreshCw } from 'lucide-react'
1+
import { Loader2, CheckCircle2, AlertTriangle, Search, Building2, UserPlus, UserMinus, RefreshCw, Clock } from 'lucide-react'
22
import { useState, useEffect } from 'react'
3-
import { useAccount, useReadContract } from 'wagmi'
4-
import { useGovernance } from '../../hooks/useGovernance'
3+
import { useReadContract } from 'wagmi'
54
import { useCRSetManagement } from '../../hooks/useCRSetManagement'
65
import { useDIDSync, useReadCID } from '../../hooks/useDIDSync'
7-
import { REGISTRY_ADDRESS, REGISTRY_ABI, TRUST_ANCHOR_ADDRESS } from '../../lib/contracts'
6+
import { REGISTRY_ADDRESS, REGISTRY_ABI, TRUST_ANCHOR_ADDRESS, CRSET_REGISTRY_ADDRESS, CRSET_REGISTRY_ABI } from '../../lib/contracts'
87
import { isAddress } from 'viem'
98
import { toast } from 'sonner'
109

1110
export function CompaniesPage() {
12-
const { isConnected } = useAccount()
1311
const [inputAddress, setInputAddress] = useState('')
1412
const [debouncedAddress, setDebouncedAddress] = useState<`0x${string}` | undefined>(undefined)
1513

1614
// State for Admin Tools
1715
const [adminAddress, setAdminAddress] = useState('')
1816

1917
// Hooks
20-
const { proposeCompanyRegistration, isPending } = useGovernance()
2118
const { addCompanyAdmin, removeCompanyAdmin, isPending: isAdminPending, isSuccess: isAdminSuccess } = useCRSetManagement()
2219
const { syncCIDToDID, isPending: isSyncPending, isSuccess: isSyncSuccess } = useDIDSync()
2320
const { cid: companyCID, isLoading: isCIDLoading } = useReadCID(debouncedAddress)
@@ -34,29 +31,41 @@ export function CompaniesPage() {
3431
return () => clearTimeout(timer)
3532
}, [inputAddress])
3633

37-
// Notifications for side-effects
34+
// Notifications
3835
useEffect(() => {
3936
if (isAdminSuccess) toast.success("Admin Updated Successfully")
4037
if (isSyncSuccess) toast.success("DID Document Synced Successfully")
4138
}, [isAdminSuccess, isSyncSuccess])
4239

43-
// READ Status
44-
const { data: currentOwner, isLoading: isChecking } = useReadContract({
40+
// 1. READ: Identity Owner
41+
const { data: currentOwner, isLoading: isCheckingOwner } = useReadContract({
4542
address: REGISTRY_ADDRESS,
4643
abi: REGISTRY_ABI,
4744
functionName: 'identityOwner',
4845
args: debouncedAddress ? [debouncedAddress] : undefined,
4946
query: { enabled: !!debouncedAddress }
5047
})
5148

52-
// Determine Status
49+
// 2. READ: Is Already Admin (Registered)
50+
const { data: isRegisteredAdmin, isLoading: isCheckingAdmin } = useReadContract({
51+
address: CRSET_REGISTRY_ADDRESS,
52+
abi: CRSET_REGISTRY_ABI,
53+
functionName: 'isCompanyAdmin',
54+
args: debouncedAddress ? [debouncedAddress, debouncedAddress] : undefined, // Check if company is admin of itself
55+
query: { enabled: !!debouncedAddress }
56+
})
57+
58+
const isLoading = isCheckingOwner || isCheckingAdmin
59+
60+
// --- LOGIC: 3 STATES ---
5361
const isManaged = currentOwner && TRUST_ANCHOR_ADDRESS &&
5462
currentOwner.toLowerCase() === TRUST_ANCHOR_ADDRESS.toLowerCase()
5563

56-
const handleRegister = () => {
57-
if (!debouncedAddress) return
58-
proposeCompanyRegistration(debouncedAddress)
59-
}
64+
// State 1: Unmanaged (Needs Delegation)
65+
const isUnmanaged = !isManaged
66+
67+
// State 2: Delegated but NOT Registered (Needs Action from TA)
68+
const isPendingRegistration = isManaged && !isRegisteredAdmin
6069

6170
// Admin Handlers
6271
const handleAddAdmin = () => {
@@ -91,66 +100,81 @@ export function CompaniesPage() {
91100
</div>
92101
)
93102

94-
if (isChecking) return (
103+
if (isLoading) return (
95104
<div className="text-center py-12 text-slate-500">
96105
<Loader2 className="w-10 h-10 mx-auto mb-3 animate-spin text-indigo-500" />
97106
<p>Verifying Identity Status...</p>
98107
</div>
99108
)
100109

101-
return (
102-
<div className="animate-in fade-in slide-in-from-bottom-2">
103-
<div className={`p-6 rounded-xl border-2 ${
104-
isManaged ? 'border-green-200 bg-green-50/50' : 'border-amber-200 bg-amber-50/50'
105-
}`}>
106-
<div className="flex items-start gap-4">
107-
<div className={`p-3 rounded-full ${
108-
isManaged ? 'bg-green-100 text-green-600' : 'bg-amber-100 text-amber-600'
109-
}`}>
110-
{isManaged ? <CheckCircle2 className="w-6 h-6"/> : <AlertTriangle className="w-6 h-6"/>}
111-
</div>
112-
<div className="flex-1">
113-
<h4 className="text-lg font-bold text-slate-900">
114-
{isManaged ? 'Identity is Managed' : 'Action Required'}
115-
</h4>
116-
<p className="text-slate-600 mt-1">
117-
{isManaged
118-
? "This identity is correctly delegated to the Trust Anchor."
119-
: "This identity is NOT controlled by the Trust Anchor."}
120-
</p>
121-
122-
{!isManaged && (
123-
<div className="mt-4 bg-white p-4 rounded-lg border border-amber-200 text-sm text-slate-600">
124-
<strong>Next Step:</strong> The company must delegate control using their wallet via the Company Onboarding portal.
125-
</div>
126-
)}
127-
</div>
128-
</div>
129-
</div>
110+
// STATE 1: Unmanaged (Red)
111+
if (isUnmanaged) {
112+
return (
113+
<div className="animate-in fade-in slide-in-from-bottom-2">
114+
<div className="p-6 rounded-xl border-2 border-red-200 bg-red-50/50">
115+
<div className="flex items-start gap-4">
116+
<div className="p-3 rounded-full bg-red-100 text-red-600">
117+
<AlertTriangle className="w-6 h-6"/>
118+
</div>
119+
<div className="flex-1">
120+
<h4 className="text-lg font-bold text-slate-900">Action Required: Delegation</h4>
121+
<p className="text-slate-600 mt-1">
122+
This identity is NOT controlled by the Trust Anchor. The company must delegate control first via the Onboarding page.
123+
</p>
124+
</div>
125+
</div>
126+
</div>
127+
</div>
128+
)
129+
}
130130

131-
{isManaged && (
132-
<div className="mt-6">
133-
<button
134-
onClick={handleRegister}
135-
disabled={isPending || !isConnected}
136-
className="w-full py-3 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg font-bold flex items-center justify-center transition-colors shadow-sm disabled:opacity-50"
137-
>
138-
{isPending ? (
139-
<><Loader2 className="w-5 h-5 mr-2 animate-spin" /> Creating Proposal...</>
140-
) : (
141-
<><Plus className="w-5 h-5 mr-2" /> Register Company (Create Proposal)</>
142-
)}
143-
</button>
144-
<p className="text-xs text-center text-slate-400 mt-3">
145-
This will create a governance proposal to officialy register the company.
146-
</p>
147-
</div>
148-
)}
149-
</div>
131+
// STATE 2: Pending Registration (Yellow)
132+
if (isPendingRegistration) {
133+
return (
134+
<div className="animate-in fade-in slide-in-from-bottom-2">
135+
<div className="p-6 rounded-xl border-2 border-amber-300 bg-amber-50">
136+
<div className="flex items-start gap-4">
137+
<div className="p-3 rounded-full bg-amber-100 text-amber-700">
138+
<Clock className="w-6 h-6"/>
139+
</div>
140+
<div className="flex-1">
141+
<h4 className="text-lg font-bold text-slate-900">Identity Managed (Step 1 Complete)</h4>
142+
<p className="text-slate-700 mt-1 text-sm">
143+
The Trust Anchor owns this identity, but the company wallet has no write access yet.
144+
</p>
145+
<div className="mt-4 p-3 bg-white/80 rounded border border-amber-200 text-amber-800 text-sm font-medium flex items-center gap-2">
146+
<UserPlus className="w-4 h-4" />
147+
Action Required: Add this address to "CRSet Admins" below.
148+
</div>
149+
</div>
150+
</div>
151+
</div>
152+
</div>
153+
)
154+
}
155+
156+
// STATE 3: Fully Registered (Green)
157+
return (
158+
<div className="animate-in fade-in slide-in-from-bottom-2">
159+
<div className="p-6 rounded-xl border-2 border-green-200 bg-green-50/50">
160+
<div className="flex items-start gap-4">
161+
<div className="p-3 rounded-full bg-green-100 text-green-600">
162+
<CheckCircle2 className="w-6 h-6"/>
163+
</div>
164+
<div className="flex-1">
165+
<h4 className="text-lg font-bold text-slate-900">Fully Verified</h4>
166+
<p className="text-slate-600 mt-1">
167+
Identity is managed and the company has full admin access to their CRSet.
168+
</p>
169+
</div>
170+
</div>
171+
</div>
172+
{/* No Register Button here - it's already done */}
173+
</div>
150174
)
151175
}
152176

153-
// --- RESTORED FUNCTIONALITY ---
177+
// ... (Advanced Tools render remains the same)
154178
const renderAdvancedTools = () => {
155179
if (!isManaged || !debouncedAddress) return null;
156180

@@ -250,7 +274,7 @@ export function CompaniesPage() {
250274
</div>
251275
</div>
252276

253-
{/* Restored Advanced Tools */}
277+
{/* Advanced Tools */}
254278
{renderAdvancedTools()}
255279
</div>
256280
)

0 commit comments

Comments
 (0)