Spaces:
Running
Running
UI API Integration Prompt Instructions
π― System Overview
You are building a UI for a hierarchical B2B beauty supply chain management system. The backend provides REST APIs for managing merchants in a 4-level hierarchy: Parent Company β cnf β distributors β retails.
ποΈ API Base Configuration
Base URL & Authentication
const API_BASE_URL = 'http://localhost:8000'
const API_ENDPOINTS = {
merchants: '/merchants',
merchantSettings: '/merchant-settings',
users: '/system-users',
roles: '/access-roles',
auth: '/auth'
}
// JWT Token Authentication (implement as needed)
const apiHeaders = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('authToken')}`
}
Test Credentials for Development
const TEST_CREDENTIALS = {
superAdmin: { username: 'superadmin', password: 'SuperAdmin@123' },
companyAdmin: { username: 'companyadmin', password: 'CompanyAdmin@123' },
cnfManager: { username: 'cnfmanager_north', password: 'cnfManager@123' },
distManager: { username: 'distmanager_delhi', password: 'DistManager@123' },
retailOwner: { username: 'owner_cp_luxury', password: 'retailOwner@123' }
}
π± Core UI Components to Build
1. Merchant Hierarchy Tree View
// GET /merchants - Fetch all merchants
const fetchMerchantsHierarchy = async () => {
const response = await fetch(`${API_BASE_URL}/merchants`, {
headers: apiHeaders
})
const merchants = await response.json()
// Build tree structure
return buildHierarchyTree(merchants)
}
// Expected merchant object structure:
const merchantStructure = {
merchant_id: "string",
merchant_name: "string",
merchant_type: "parent_company|cnf|distributor|retail",
merchant_code: "string",
parent_merchant_id: "string|null",
status: "active|inactive",
contact: {
phone: "string",
email: "string",
address_line1: "string",
city: "string",
state: "string",
pincode: "string"
},
kyc: { /* GST, PAN details */ }
}
2. Merchant Management Dashboard
Create these UI sections:
A. Merchant List/Grid View
// API Calls:
// GET /merchants?merchant_type=retail - Filter by type
// GET /merchants?status=active - Filter by status
// GET /merchants/children/{parent_id} - Get child merchants
const merchantListConfig = {
columns: [
{ key: 'merchant_code', label: 'Code', sortable: true },
{ key: 'merchant_name', label: 'Name', sortable: true },
{ key: 'merchant_type', label: 'Type', filterable: true },
{ key: 'contact.city', label: 'City' },
{ key: 'status', label: 'Status', filterable: true },
{ key: 'actions', label: 'Actions' }
],
filters: ['merchant_type', 'status', 'city'],
actions: ['view', 'edit', 'settings', 'delete']
}
B. Merchant Creation Form
// POST /merchants - Create new merchant
const createMerchantForm = {
fields: {
merchant_name: { type: 'text', required: true },
merchant_type: {
type: 'select',
options: ['cnf', 'distributor', 'retail'],
required: true
},
parent_merchant_id: {
type: 'autocomplete',
source: '/merchants', // Dynamic based on type
required: true
},
contact: {
phone: { type: 'tel', required: true },
email: { type: 'email', required: true },
address_line1: { type: 'text', required: true },
city: { type: 'text', required: true },
state: { type: 'select', options: 'INDIAN_STATES' },
pincode: { type: 'text', pattern: '[0-9]{6}' }
},
kyc: {
gst_number: { type: 'text', pattern: 'GST_REGEX' },
pan_number: { type: 'text', pattern: 'PAN_REGEX' }
}
},
validation: 'client-side + server-side'
}
3. Merchant Settings Management
// GET /merchant-settings/{merchant_id} - Fetch settings
// PUT /merchant-settings/{merchant_id} - Update settings
const merchantSettingsForm = {
businessSettings: {
auto_allocate_stock: { type: 'toggle' },
credit_limit: { type: 'currency', min: 0 },
payment_terms_days: { type: 'number', min: 0, max: 365 }
},
inventorySettings: {
low_stock_threshold: { type: 'number', min: 1 },
enable_backorder: { type: 'toggle' },
auto_reorder: { type: 'toggle' }
},
notifications: {
email_notifications: { type: 'toggle' },
sms_notifications: { type: 'toggle' },
low_stock_alerts: { type: 'toggle' }
},
operatingHours: {
// Dynamic day-wise hour picker
format: { open_time: 'HH:mm', close_time: 'HH:mm', is_open: boolean }
},
pricing: {
default_markup_percentage: { type: 'percentage', min: 0, max: 100 },
allow_discount: { type: 'toggle' },
max_discount_percentage: { type: 'percentage', min: 0, max: 50 }
},
taxSettings: {
gst_rate: { type: 'percentage', default: 18 },
inclusive_pricing: { type: 'toggle' },
tax_exemption: { type: 'toggle' }
}
}
4. User & Role Management
// GET /access-roles - Fetch all roles
// GET /system-users - Fetch all users
// POST /system-users - Create user
const userManagementConfig = {
userForm: {
username: { type: 'text', unique: true },
email: { type: 'email', unique: true },
full_name: { type: 'text' },
role_id: {
type: 'select',
source: '/access-roles',
displayField: 'role_name'
},
merchant_id: {
type: 'autocomplete',
source: '/merchants',
filter: 'based on role permissions'
},
password: { type: 'password', minLength: 8 }
},
roleBasedAccess: {
// Show/hide features based on user role
'role_super_admin': 'ALL_FEATURES',
'role_company_admin': 'EXCLUDE_DELETE_OPERATIONS',
'role_cnf_manager': 'REGIONAL_SCOPE_ONLY',
'role_distributor_manager': 'LOCAL_SCOPE_ONLY',
'role_retail_owner': 'OWN_MERCHANT_ONLY'
}
}
π Key API Integration Patterns
1. Hierarchical Data Loading
// Pattern: Load parent first, then children on-demand
const loadHierarchicalData = async (parentId = null) => {
if (!parentId) {
// Load root level (Parent Company + cnfs)
return await fetch(`${API_BASE_URL}/merchants?merchant_type=parent_company,cnf`)
} else {
// Load children of specific parent
return await fetch(`${API_BASE_URL}/merchants/children/${parentId}`)
}
}
// Tree expansion pattern
const expandTreeNode = async (nodeId) => {
const children = await fetch(`${API_BASE_URL}/merchants/children/${nodeId}`)
// Update tree state with children
}
2. Context-Aware Form Fields
// Parent selection based on merchant type
const getParentOptions = async (merchantType) => {
const parentTypes = {
'cnf': ['parent_company'],
'distributor': ['cnf'],
'retail': ['distributor']
}
const parentType = parentTypes[merchantType]?.[0]
if (parentType) {
return await fetch(`${API_BASE_URL}/merchants?merchant_type=${parentType}`)
}
}
// Settings defaults based on merchant type
const getSettingsDefaults = (merchantType) => {
const defaults = {
'cnf': { credit_limit: 10000000, payment_terms_days: 90, markup: 5 },
'distributor': { credit_limit: 3000000, payment_terms_days: 60, markup: 15 },
'retail': { credit_limit: 500000, payment_terms_days: 30, markup: 30 }
}
return defaults[merchantType] || {}
}
3. Error Handling & Validation
const apiErrorHandler = (error) => {
const errorMessages = {
400: 'Invalid request data. Please check your input.',
401: 'Authentication required. Please login.',
403: 'You do not have permission for this action.',
404: 'Resource not found.',
409: 'Duplicate entry. This record already exists.',
422: 'Validation failed. Please check highlighted fields.',
500: 'Server error. Please try again later.'
}
return errorMessages[error.status] || 'An unexpected error occurred.'
}
// Form validation
const validateMerchantForm = (data) => {
const errors = {}
if (!data.merchant_name?.trim()) {
errors.merchant_name = 'Merchant name is required'
}
if (data.merchant_type === 'retail' && !data.parent_merchant_id) {
errors.parent_merchant_id = 'Parent distributor is required for retails'
}
// GST validation for Indian businesses
if (data.kyc?.gst_number && !/^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/.test(data.kyc.gst_number)) {
errors['kyc.gst_number'] = 'Invalid GST number format'
}
return errors
}
π¨ UI/UX Implementation Guidelines
1. Responsive Design Requirements
/* Mobile-first approach for merchant management */
.merchant-card {
/* Stack vertically on mobile */
@media (max-width: 768px) {
flex-direction: column;
}
}
.merchant-hierarchy-tree {
/* Horizontal scroll on mobile */
@media (max-width: 768px) {
overflow-x: auto;
white-space: nowrap;
}
}
2. State Management Pattern
// Redux/Zustand store structure
const merchantStore = {
state: {
merchants: [],
selectedMerchant: null,
hierarchyTree: {},
filters: { type: 'all', status: 'active' },
loading: false,
error: null
},
actions: {
fetchMerchants: async (filters) => { },
createMerchant: async (data) => { },
updateMerchant: async (id, data) => { },
deleteMerchant: async (id) => { },
setSelectedMerchant: (merchant) => { },
setFilters: (filters) => { }
}
}
3. Component Architecture
// Component hierarchy
const ComponentStructure = {
'MerchantDashboard': {
'MerchantHierarchyTree': ['TreeNode', 'TreeNodeActions'],
'MerchantListView': ['MerchantCard', 'FilterBar', 'Pagination'],
'MerchantFormModal': ['FormFields', 'ValidationErrors'],
'MerchantSettingsPanel': ['SettingsSections', 'OperatingHours']
},
'UserManagement': {
'UserListView': ['UserCard', 'RoleFilter'],
'UserFormModal': ['UserForm', 'RoleSelector'],
'PermissionsMatrix': ['RolePermissions']
}
}
π Testing Checklist
1. API Integration Tests
- Fetch merchants hierarchy successfully
- Create merchant with valid parent relationship
- Update merchant settings with validation
- Handle API errors gracefully
- Implement proper loading states
2. UI Functionality Tests
- Tree view expands/collapses correctly
- Form validation works client-side
- Filter/search functionality
- Responsive design on mobile
- Role-based feature visibility
3. Business Logic Tests
- cnf can only have Parent Company as parent
- distributor can only have cnf as parent
- retail can only have distributor as parent
- Credit limits are enforced based on merchant type
- Operating hours format validation
π Development Workflow
1. Setup & Configuration
# Start the API server
uvicorn app.main:app --reload --port 8000
# Access API documentation
open http://localhost:8000/docs
# Test API endpoints
curl -X GET "http://localhost:8000/merchants" -H "Content-Type: application/json"
2. Implementation Order
- Phase 1: Basic merchant CRUD operations
- Phase 2: Hierarchy tree view and navigation
- Phase 3: Merchant settings management
- Phase 4: User and role management
- Phase 5: Advanced features (reports, analytics)
3. Data Flow Examples
// Example: Creating a new retail
const createretail = async (retailData) => {
// 1. Validate form data
const errors = validateMerchantForm(retailData)
if (Object.keys(errors).length > 0) {
return { success: false, errors }
}
// 2. Call API
const response = await fetch(`${API_BASE_URL}/merchants`, {
method: 'POST',
headers: apiHeaders,
body: JSON.stringify({...retailData, merchant_type: 'retail'})
})
// 3. Handle response
if (response.ok) {
const newretail = await response.json()
// Update local state
addMerchantToStore(newretail)
// Create default settings
await createDefaultSettings(newretail.merchant_id)
return { success: true, data: newretail }
} else {
const error = await response.json()
return { success: false, error: error.detail }
}
}
π§ Common Implementation Patterns
1. Autocomplete for Parent Selection
const ParentMerchantSelector = ({ merchantType, value, onChange }) => {
const [options, setOptions] = useState([])
useEffect(() => {
const loadParentOptions = async () => {
const parentType = getParentType(merchantType)
const response = await fetch(`${API_BASE_URL}/merchants?merchant_type=${parentType}`)
setOptions(await response.json())
}
if (merchantType) {
loadParentOptions()
}
}, [merchantType])
return (
<Autocomplete
options={options}
getOptionLabel={(option) => `${option.merchant_name} (${option.merchant_code})`}
value={value}
onChange={onChange}
placeholder="Select parent merchant..."
/>
)
}
2. Operating Hours Component
const OperatingHoursEditor = ({ value, onChange }) => {
const days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
return (
<div className="operating-hours-grid">
{days.map(day => (
<div key={day} className="day-row">
<label>{day.charAt(0).toUpperCase() + day.slice(1)}</label>
<input
type="checkbox"
checked={value[day]?.is_open || false}
onChange={(e) => onChange(day, 'is_open', e.target.checked)}
/>
{value[day]?.is_open && (
<>
<input
type="time"
value={value[day]?.open_time || '09:00'}
onChange={(e) => onChange(day, 'open_time', e.target.value)}
/>
<input
type="time"
value={value[day]?.close_time || '18:00'}
onChange={(e) => onChange(day, 'close_time', e.target.value)}
/>
</>
)}
</div>
))}
</div>
)
}
This prompt provides comprehensive guidance for building a production-ready UI that integrates seamlessly with your hierarchical merchant API system.