x.value);
REG.crops=document.getElementById('regCrops').value;
REG.seeds=document.getElementById('regSeeds').value;
REG.fertilisers=document.getElementById('regFerts').value;
REG.pesticides=document.getElementById('regPests').value;
REG.animalFeeds=document.getElementById('regFeeds').value;
}
try{
toast('Sending OTP to '+REG.phone+'...','i');
await api('POST','/auth/send-otp',{phone:REG.phone});
document.getElementById('otpPhoneShow').textContent=REG.phone;
goStep(4);toast('OTP sent! Check your phone.','s');
}catch(e){toast('Error sending OTP: '+e.message,'e');}
}
}
function prv(){if(S.step>1)goStep(S.step-1);}
function otpFwd(i){
const els=document.querySelectorAll('.otp-input');
if(els[i].value.length===1&&i<5)els[i+1].focus();
if(els[i].value.length===0&&i>0)els[i-1].focus();
}
async function verifyOTP(){
const code=[...document.querySelectorAll('.otp-input')].map(x=>x.value).join('');
if(code.length!==6){toast('Enter the 6-digit code','e');return;}
try{
await api('POST','/auth/verify-otp',{phone:REG.phone,code});
goStep(5);toast('Phone verified! Now enable GPS.','s');
}catch(e){toast('Wrong code: '+e.message,'e');}
}
async function resendOTP(){
try{await api('POST','/auth/send-otp',{phone:REG.phone});toast('New OTP sent!','s');}
catch(e){toast('Error: '+e.message,'e');}
}
async function finishReg(){
if(!S.gps){toast('Please enable GPS first','e');return;}
REG.gps=S.gps;
const fb=document.getElementById('finishBtn');
fb.textContent='โณ Creating account...';fb.disabled=true;
try{
const data=await api('POST','/auth/register',REG);
S.token=data.token;S.user=data.user;
toast('Welcome, '+data.user.name+'!','s');
enterApp(data.user);
}catch(e){
toast('Registration failed: '+e.message,'e');
fb.textContent='๐ Create My Account';fb.disabled=false;fb.style.opacity='1';
}
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ LOGIN โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
async function doLogin(){
const role=document.getElementById('loginRole').value;
const phone=document.getElementById('loginPhone').value.trim();
const pass=document.getElementById('loginPass').value;
if(!role||!phone||!pass){toast('Fill all fields','e');return;}
try{
const data=await api('POST','/auth/login',{phone,password:pass,role});
S.token=data.token;S.user=data.user;
startGPSWatch();toast('Welcome back, '+data.user.name+'!','s');
enterApp(data.user);
}catch(e){toast('Login failed: '+e.message,'e');}
}
function doLogout(){
S.token=null;S.user=null;S.cart=[];
if(S.gpsWid)navigator.geolocation.clearWatch(S.gpsWid);
showLanding();toast('Logged out','i');
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ ENTER APP โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function enterApp(user){
showScr('screenApp');
document.getElementById('urlRP').textContent=user.role;
document.getElementById('hdrRoleBadge').textContent=user.role.toUpperCase();
document.getElementById('hdrName').textContent=user.name;
document.getElementById('appRL').textContent={farmer:'Farmer Dashboard',agrovet:'Agrovet Dashboard',agent:'Agent Dashboard',manufacturer:'Manufacturer Dashboard',admin:'Admin Dashboard'}[user.role]||'Dashboard';
document.getElementById('cartBtn').style.display=user.role==='farmer'?'flex':'none';
buildTabs(user.role);
startGPSWatch();
renderSec(defSec(user.role));
}
function defSec(r){return{farmer:'shop',agrovet:'mystock',agent:'orders',manufacturer:'mystock',admin:'dashboard'}[r]||'shop';}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ TABS โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
const TABS={
farmer:[{id:'shop',lb:'๐ Shop'},{id:'myorders',lb:'๐ฆ My Orders'},{id:'loyalty',lb:'โญ Loyalty'},{id:'wholesale',lb:'๐ Wholesale'},{id:'track',lb:'๐ Track'},{id:'events',lb:'๐
Events'},{id:'profile',lb:'๐ค Profile'}],
agrovet:[{id:'mystock',lb:'๐ฆ My Stock'},{id:'orders',lb:'๐ Orders'},{id:'analytics',lb:'๐ Analytics'},{id:'advertise',lb:'๐ฃ Advertise'},{id:'events',lb:'๐
Events'},{id:'profile',lb:'๐ค Profile'}],
agent:[{id:'orders',lb:'๐ Available Orders'},{id:'transit',lb:'๐๏ธ In Transit'},{id:'nearby',lb:'๐ Agrovets Near Me'},{id:'events',lb:'๐
Events'},{id:'profile',lb:'๐ค Profile'}],
manufacturer:[{id:'mystock',lb:'๐ญ My Products'},{id:'analytics',lb:'๐ Analytics'},{id:'advertise',lb:'๐ฃ Advertise'},{id:'events',lb:'๐
Events'},{id:'profile',lb:'๐ค Profile'}],
admin:[{id:'dashboard',lb:'๐ Dashboard'},{id:'products',lb:'๐ฟ Products'},{id:'orders',lb:'๐ All Orders'},{id:'events',lb:'๐
Events'},{id:'profile',lb:'๐ค Profile'}],
};
function buildTabs(role){
const tabs=TABS[role]||TABS.farmer;
// Desktop
document.getElementById('dTabBar').innerHTML=tabs.map((t,i)=>`${t.lb} `).join('');
// Mobile (max 5)
document.getElementById('mTabBar').innerHTML=tabs.slice(0,5).map((t,i)=>`${t.lb.split(' ')[0]} ${t.lb.split(' ').slice(1).join(' ')} `).join('');
}
function switchSec(id,btn){
document.querySelectorAll('#dTabBar .tab-btn').forEach(b=>{b.style.color='rgba(255,255,255,.6)';b.style.fontWeight='500';b.style.borderBottom='2px solid transparent';});
if(btn.closest('#dTabBar')){btn.style.color='#fff';btn.style.fontWeight='700';btn.style.borderBottom='2px solid #f0b429';}
document.querySelectorAll('[data-mb]').forEach(b=>b.classList.remove('active'));
if(btn.closest('#mTabBar'))btn.classList.add('active');
document.querySelectorAll('.dashboard-section').forEach(s=>s.classList.remove('active'));
const sec=document.getElementById('sec-'+id);if(sec)sec.classList.add('active');
renderSec(id);
}
function renderSec(id){
({shop:rShop,mystock:rMyStock,orders:rOrders,myorders:rMyOrders,transit:rTransit,loyalty:rLoyalty,wholesale:rWholesale,track:rTrack,events:rEvents,advertise:rAdvertise,analytics:rAnalytics,dashboard:rAdminDash,products:rAdminProds,profile:rProfile,nearby:rNearby}[id]||function(){})();
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ SHOP โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rShop(){
const role=S.user?.role,s=document.getElementById('sec-shop');
if(role==='manufacturer'){s.innerHTML=`๐ฆ
No products listed yet. Add your first product for Sincy Group approval.
+ Add New Product `;return;}
const cats=['All','Seeds','Fertilisers','Feeds','Pesticides'];
const visible=catF==='All'?PRODS:PRODS.filter(p=>p.cat===catF);
s.innerHTML=`
${role==='farmer'?`
๐ Wholesale Purchase Available Cooperative heads and farmer groups: make bulk purchases above KSh 200,000 at special pricing.
Make Wholesale Purchase โ `:''}
${cats.map(c=>`${c} `).join('')}
${visible.map(p=>prodCard(p,role)).join('')}
`;
}
function prodCard(p,role){
const isAv=role==='agrovet';
const action=isAv?``:
role==='farmer'?`+ Add to Cart `:
`Stock: ${p.stock}
`;
return `
${p.ic}
${p.cat}
${p.name}
${p.unit} ยท ${p.sup}
KSh ${p.price.toLocaleString()}
${action}
`;
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ CART โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function addToCart(pid){
const p=PRODS.find(x=>x.id===pid);if(!p)return;
const ex=S.cart.find(x=>x.id===pid);
ex?ex.qty++:S.cart.push({...p,qty:1});
updCartBadge();toast(p.name+' added!','s');rCart();
}
function updCartBadge(){
const tot=S.cart.reduce((a,b)=>a+b.qty,0);
const b=document.getElementById('cartCnt');b.textContent=tot;b.style.display=tot?'flex':'none';
}
function toggleCart(){
const d=document.getElementById('cartDrawer'),o=document.getElementById('cartOverlay');
const open=d.style.right==='0px';
d.style.right=open?'-420px':'0px';
o.style.display=open?'none':'block';
if(!open)rCart();
}
function rCart(){
const body=document.getElementById('cartBody'),foot=document.getElementById('cartFoot');
if(!S.cart.length){body.innerHTML='';foot.innerHTML='';return;}
const tot=S.cart.reduce((a,b)=>a+b.price*b.qty,0);
body.innerHTML=S.cart.map(item=>`
${item.ic}
${item.name}
${item.unit} ยท KSh ${item.price.toLocaleString()} each
โ
${item.qty}
+
Remove
KSh ${(item.price*item.qty).toLocaleString()}
`).join('');
foot.innerHTML=`
Subtotal KSh ${tot.toLocaleString()}
Delivery KSh 200
Total KSh ${(tot+200).toLocaleString()}
Choose Payment Method:
๐ต
Cash on Delivery
Pay when delivered
๐ฒ
Pay via M-Pesa
STK push to phone
Proceed to Order โ `;
}
function pickPay(m){S.payMethod=m;rCart();}
function chgQty(id,d){const it=S.cart.find(x=>x.id===id);if(!it)return;it.qty+=d;if(it.qty<=0)S.cart=S.cart.filter(x=>x.id!==id);updCartBadge();rCart();}
function rmCart(id){S.cart=S.cart.filter(x=>x.id!==id);updCartBadge();rCart();}
async function doCheckout(){
if(!S.payMethod){toast('Select a payment method','e');return;}
if(!S.cart.length){toast('Your cart is empty','e');return;}
const tot=S.cart.reduce((a,b)=>a+b.price*b.qty,0)+200;
try{
const data=await api('POST','/orders',{items:S.cart.map(i=>({productId:i.id,name:i.name,qty:i.qty,price:i.price,unit:i.unit})),total:tot,paymentMethod:S.payMethod,gps:S.gps,createdAt:new Date().toISOString()},true);
toast('Order placed! '+data.message,'s');
S.cart=[];updCartBadge();S.payMethod=null;toggleCart();
}catch(e){toast('Order failed: '+e.message,'e');}
}
async function addStock(pid){
const qty=parseInt(document.getElementById('st-'+pid)?.value||0);
const price=parseInt(document.getElementById('pr-'+pid)?.value||0);
if(!qty||qty<=0){toast('Enter a valid quantity','e');return;}
try{await api('POST','/stock',{productId:pid,qty,sellingPrice:price},true);toast('Stock updated: +'+qty+' units','s');document.getElementById('st-'+pid).value='';}
catch(e){toast('Stock update failed: '+e.message,'e');}
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ MY STOCK โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rMyStock(){
const s=document.getElementById('sec-mystock');
const role=S.user?.role;
s.innerHTML=`
${role==='manufacturer'?'My Products':'My Stock'}
+ Add New Product
${role==='agrovet'?'
๐ Products you add are sent for Sincy Group approval before going live on the marketplace.
':''}
${PRODS.map(p=>prodCard(p,role)).join('')}
`;
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ ORDERS โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rOrders(){
const s=document.getElementById('sec-orders');
const role=S.user?.role;
if(role==='agent'){
s.innerHTML=`
Available Orders
Orders near your GPS location. Accept to start delivery.
${[{id:'ORD-24601',items:'DH04 Seeds x2, DAP x1',av:'Nakuru Central Agrovet',dist:'1.2km',tot:10800},{id:'ORD-24598',items:'Unga Layers Mash x3',av:'Lanet Agrovet',dist:'3.4km',tot:9600}].map(o=>`
${o.id}
${o.av} ยท ๐ ${o.dist}
Ready for Pickup
${o.items}
KSh ${o.tot.toLocaleString()}
โ
Ready Order
๐ฆ Receive for Delivery
`).join('')}
`;
} else if(role==='agrovet'){
s.innerHTML=`
Incoming Orders
๐ฑ You receive SMS notifications on your phone for every new order via Africa's Talking.
${[{id:'ORD-24601',county:'Nakuru',items:'DH04 Seeds x2, DAP x1',tot:10800,pay:'M-Pesa',st:'New'},{id:'ORD-24599',county:'Nakuru',items:'Unga Dairy Meal x4',tot:11600,pay:'Cash on Delivery',st:'Confirmed'}].map(o=>`
${o.id} ยท ${o.county} County
Payment: ${o.pay}
${o.st}
${o.items}
KSh ${o.tot.toLocaleString()}
${o.st==='New'?`
โ
Confirm Order (SMS farmer) `:`
โ
Confirmed โ farmer notified via SMS `}
`).join('')}
`;
} else {
s.innerHTML=`
All Orders
${['Order ID','County','Items','Amount','Payment','Status','GPS'].map(h=>`${h} `).join('')}
${[{id:'ORD-24601',cty:'Nakuru',items:'DH04 x2, DAP x1',amt:10800,pay:'M-Pesa',st:'Delivered',gps:'-0.28, 36.07'},{id:'ORD-24599',cty:'Kiambu',items:'Dairy Meal x4',amt:11600,pay:'Cash',st:'In Transit',gps:'-1.17, 36.93'},{id:'ORD-24598',cty:'Nakuru',items:'Layers Mash x3',amt:9600,pay:'M-Pesa',st:'Confirmed',gps:'-0.31, 36.10'}].map(o=>`${o.id} ${o.cty} ${o.items} KSh ${o.amt.toLocaleString()} ${o.pay} ${o.st} ${o.gps} `).join('')}
`;
}
}
async function confirmOrder(id){
try{await api('PATCH','/orders/'+id+'/status',{status:'confirmed'},true);toast('Order confirmed! Farmer notified via SMS.','s');rOrders();}
catch(e){toast('Error: '+e.message,'e');}
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ MY ORDERS (FARMER) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rMyOrders(){
const s=document.getElementById('sec-myorders');
s.innerHTML=`
My Orders
${[{id:'ORD-24601',dt:'Jan 15, 2026 09:32',items:'DH04 Seeds x2, DAP x1',tot:10800,pay:'M-Pesa',st:'Delivered'},{id:'ORD-24590',dt:'Jan 10, 2026 14:15',items:'Unga Chick Mash x2',tot:6200,pay:'Cash on Delivery',st:'Delivered'}].map(o=>`
${o.id}
${o.dt} ยท ${o.pay}
${o.st}
${o.items}
KSh ${o.tot.toLocaleString()}
`).join('')}
`;
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ TRANSIT โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rTransit(){
const s=document.getElementById('sec-transit');
s.innerHTML=`
Orders In Transit
ORD-24595
๐ Delivering to Nakuru Town ยท 2.1km remaining
๐ด In Transit
DH04 Seeds x3, Roundup x1
KSh 8,300
โ
Mark as Delivered
`;
}
async function markDel(id){
try{await api('PATCH','/orders/'+id+'/status',{status:'delivered'},true);toast('Delivery confirmed! Farmer notified via SMS.','s');rTransit();}
catch(e){toast('Error: '+e.message,'e');}
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ NEARBY โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rNearby(){
const s=document.getElementById('sec-nearby');
s.innerHTML=`
Agrovets Near Me
Based on your current GPS location
${[{name:'Nakuru Central Agrovet',dist:'0.8km',cty:'Nakuru',st:'Open',hrs:'7am-6pm'},{name:'Lanet Agrovet Centre',dist:'2.3km',cty:'Nakuru',st:'Open',hrs:'8am-5pm'},{name:'Njoro Farmers Supply',dist:'5.1km',cty:'Nakuru',st:'Closed',hrs:'8am-5pm'}].map(av=>`
๐ช ${av.name}
๐ ${av.dist} ยท ${av.cty} ยท โฐ ${av.hrs}
${av.st}
`).join('')}
`;
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ LOYALTY โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rLoyalty(){
const s=document.getElementById('sec-loyalty');
const ref=S.user?.referralCode||'ABF-NKR-2026-001';
s.innerHTML=`
Available Points
2,340
2,660 more points to next reward tier
Your Referral Code
Share your code. Earn 200 pts for every friend who joins and makes a first purchase.
๐ฑ Share via SMS
๐ฌ WhatsApp
๐ Copy
Redeem Points
${[{pts:'500 pts',rew:'KSh 200 discount on next order'},{pts:'1,000 pts',rew:'Free delivery (next 3 orders)'},{pts:'2,500 pts',rew:'KSh 1,000 product voucher'}].map(r=>`
${r.pts} ${r.rew}
`).join('')}
Redeem My Points โ
`;
}
function cpRef(c){navigator.clipboard?.writeText(c).then(()=>toast('Code copied!','s')).catch(()=>toast('Code: '+c,'i'));}
function shSMS(c){window.open('sms:?body='+encodeURIComponent('Join AgriBeacon! Use my referral code '+c+' to get 200 bonus points. Sign up at agribeacon.org'));}
function shWA(c){window.open('https://wa.me/?text='+encodeURIComponent('Join AgriBeacon - Africa\'s verified agri-input marketplace! Use my code '+c+' for 200 bonus points. agribeacon.org'));}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ WHOLESALE โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rWholesale(){
const s=document.getElementById('sec-wholesale');
s.innerHTML=`
Wholesale Purchasing
For Cooperatives & Farmer Groups
Coordinate bulk purchases above KSh 200,000 at preferential pricing. Ideal for cooperative heads, SACCOs and farmer groups.
`;
}
async function subWholesale(){
const g=document.getElementById('wsGroup')?.value?.trim();
if(!g){toast('Enter your cooperative name','e');return;}
try{await api('POST','/orders/wholesale',{groupName:g,members:document.getElementById('wsMembers')?.value,products:document.getElementById('wsProd')?.value,location:document.getElementById('wsLoc')?.value,preferredDate:document.getElementById('wsDate')?.value,gps:S.gps},true);toast('Wholesale request submitted! Our team will call you within 24hrs.','s');}
catch(e){toast('Error: '+e.message,'e');}
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ TRACK โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rTrack(){
const s=document.getElementById('sec-track');
s.innerHTML=`
Track Your Order
Track
${['Order Placed','Agrovet Confirmed','Agent Picked Up','Out for Delivery','Delivered'].map((st,i)=>`
${i<4?`
`:''}
${i<3?'โ':i===3?'โณ':i+1}
${st}
${i===0?'Jan 15, 09:32':i===1?'Jan 15, 10:05':i===2?'Jan 15, 11:30':i===3?'In progress...':'Pending'}
`).join('')}
`;
}
function doTrack(){const id=document.getElementById('trackId')?.value?.trim();if(!id){toast('Enter an Order ID','e');return;}document.getElementById('trackRes').style.display='block';toast('Tracking order '+id,'s');}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ EVENTS โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rEvents(){
const s=document.getElementById('sec-events');
s.innerHTML=`
Events
+ Add Event
๐ All events are reviewed and approved by Sincy Group before publishing.
${[{t:'Nakuru County Farmers Field Day',dt:'Feb 15, 2026',loc:'Nakuru Agricultural Center',org:'Sincy Group',st:'Approved'},{t:'AgriBeacon Agrovet Training Workshop',dt:'Mar 5, 2026',loc:'Nairobi โ Virtual + Physical',org:'AgriBeacon',st:'Approved'},{t:'Fertiliser Application Masterclass',dt:'Mar 20, 2026',loc:'Eldoret Agricultural College',org:'Yara East Africa',st:'Pending'}].map(ev=>`
${ev.t}
๐
${ev.dt} ยท ๐ ${ev.loc}
By: ${ev.org}
${ev.st}
`).join('')}
`;
}
async function submitEvent(){
const t=document.getElementById('evTitle')?.value?.trim();
if(!t){toast('Enter event title','e');return;}
try{await api('POST','/events',{title:t,date:document.getElementById('evDate')?.value,location:document.getElementById('evLoc')?.value,description:document.getElementById('evDesc')?.value,gps:S.gps},true);toast('Event submitted for Sincy Group approval!','s');closeModal('addEvtModal');}
catch(e){toast('Error: '+e.message,'e');}
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ ADVERTISE โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
let adType='';
function rAdvertise(){
const s=document.getElementById('sec-advertise');
s.innerHTML=`
Advertising
๐ผ๏ธ
Banner Ad
Display banner on homepage. KSh 5,000/week. Great for brand awareness.
โญ
Featured Product
Pin product at top of search results. KSh 3,000/week.
๐ฑ
SMS Campaign
Direct SMS to targeted farmers by county. KSh 2/SMS ยท min 500 farmers.
๐
County Targeting
Ads shown only in selected counties. KSh 4,000/week/county.
`;
}
function pickAd(t,el){adType=t;const titles={banner:'Create Banner Ad',featured:'Feature Your Product',sms:'Launch SMS Campaign',county:'County-Targeted Ad'};document.getElementById('adFormTitle').textContent=titles[t];document.getElementById('adForm').style.display='block';document.querySelectorAll('.ad-card').forEach(c=>c.classList.remove('sel'));el.classList.add('sel');}
async function subAd(){
const p=document.getElementById('adProd')?.value?.trim();
if(!p){toast('Enter product name','e');return;}
try{await api('POST','/advertise',{type:adType,product:p,imageUrl:document.getElementById('adImg')?.value,description:document.getElementById('adDesc')?.value,targetCounties:document.getElementById('adCnts')?.value,duration:document.getElementById('adDur')?.value},true);toast('Ad submitted for Sincy Group review!','s');}
catch(e){toast('Error: '+e.message,'e');}
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ ANALYTICS โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rAnalytics(){
const s=document.getElementById('sec-analytics');
const isMfg=S.user?.role==='manufacturer';
s.innerHTML=`
My Analytics
${(isMfg?[{v:'3,420',lb:'Bags/Litres Sold'},{v:'12',lb:'Active Products'},{v:'8',lb:'Counties Reached'},{v:'94%',lb:'Stock Fill Rate'}]:[{v:'342',lb:'Total Orders'},{v:'KSh 1.2M',lb:'Revenue (Month)'},{v:'86',lb:'Farmers Served'},{v:'98%',lb:'Delivery Rate'},{v:'4.8โญ',lb:'Rating'},{v:'23',lb:'Repeat Buyers'}]).map(c=>`
`).join('')}
Top Products (${isMfg?'Volume':'Sales'})
${[{n:'DH04 Maize Seeds',v:isMfg?'320 bags':'KSh 216,000',p:82},{n:'DAP Fertiliser',v:isMfg?'280 bags':'KSh 408,000',p:71},{n:'Unga Layers Mash',v:isMfg?'180 bags':'KSh 204,800',p:46},{n:'Roundup Herbicide',v:isMfg?'120 litres':'KSh 51,700',p:29}].map(p=>`
`).join('')}
${!isMfg?`
Sales by County ${[{c:'Nakuru',n:180,p:53},{c:'Nyandarua',n:82,p:24},{c:'Laikipia',n:50,p:15},{c:'Other',n:30,p:8}].map(c=>`
${c.c} ${c.n} orders (${c.p}%)
`).join('')}
`:''}
`;
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ ADMIN DASHBOARD โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rAdminDash(){
const s=document.getElementById('sec-dashboard');
s.innerHTML=`
Sincy Group Admin Dashboard
All platform data extracted from AWS DynamoDB.
${[{lb:'Total Farmers',v:'2,431',ic:'๐พ'},{lb:'Agrovets',v:'187',ic:'๐ช'},{lb:'Agents',v:'563',ic:'๐๏ธ'},{lb:'Manufacturers',v:'24',ic:'๐ญ'},{lb:'Total Orders',v:'8,902',ic:'๐ฆ'},{lb:'Active GPS',v:'341',ic:'๐'}].map(c=>`
`).join('')}
Live Actor GPS Mapping
๐ GPS data for all actors stored in AWS DynamoDB
Query via GET /api/admin/gps-all ยท Export via GET /api/admin/export/actors
Export GPS Data (CSV)
Recent Orders
${['Order ID','County','Items','Amount','Payment','Status','GPS'].map(h=>`${h} `).join('')}
${[{id:'ORD-24601',cty:'Nakuru',it:'DH04 x2, DAP x1',amt:10800,pay:'M-Pesa',st:'Delivered',gps:'-0.28, 36.07'},{id:'ORD-24599',cty:'Kiambu',it:'Dairy Meal x4',amt:11600,pay:'Cash',st:'In Transit',gps:'-1.17, 36.93'},{id:'ORD-24598',cty:'Nakuru',it:'Layers Mash x3',amt:9600,pay:'M-Pesa',st:'Confirmed',gps:'-0.31, 36.10'}].map(o=>`${o.id} ${o.cty} ${o.it} KSh ${o.amt.toLocaleString()} ${o.pay} ${o.st} ${o.gps} `).join('')}
`;
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ ADMIN PRODUCTS โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rAdminProds(){
const s=document.getElementById('sec-products');
s.innerHTML=`
Product Management
3 Pending Approval
โณ Pending Approval
${[{n:'BioZinc Foliar Spray 1L',by:'Njoro Agrovet',dt:'Jan 15, 2026'},{n:'AquaFarm Tilapia Pellets 25kg',by:'AquaFeed Kenya Ltd',dt:'Jan 14, 2026'},{n:'Organic Compost Activator 5kg',by:'Green Earth Agrovet',dt:'Jan 13, 2026'}].map(p=>`
${p.n}
By: ${p.by} ยท ${p.dt}
โ
Approve
โ Reject
`).join('')}
โ
Live Products (${PRODS.length})
Product Cat Price Stock Supplier
${PRODS.map(p=>`${p.ic} ${p.name} ${p.cat} KSh ${p.price.toLocaleString()} ${p.stock} ${p.sup} `).join('')}
`;
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ PROFILE โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function rProfile(){
const s=document.getElementById('sec-profile');
const u=S.user||{name:'Demo User',role:'farmer',phone:'+254712345678',referralCode:'ABF-NKR-2026-001',county:'Nakuru',joinedAt:'2026-01-15T09:32:00Z'};
const ref=u.referralCode||'ABF-NKR-2026-001';
s.innerHTML=`
${u.name.charAt(0)}
${u.name}
${u.role} Account
${ref}
Joined
${u.joinedAt?new Date(u.joinedAt).toLocaleDateString('en-GB',{day:'numeric',month:'short',year:'numeric',hour:'2-digit',minute:'2-digit'}):'โ'}
GPS Status
${S.gps?S.gps.lat.toFixed(4)+', '+S.gps.lng.toFixed(4):'Not captured'}
Your Referral Code
Share your code and earn 200 loyalty points for each friend who joins.
๐ฑ SMS
๐ฌ WhatsApp
๐ Copy
๐ช Sign Out
`;
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ ADD PRODUCT โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
async function submitProduct(){
const n=document.getElementById('npName')?.value?.trim(),cat=document.getElementById('npCat')?.value,unit=document.getElementById('npUnit')?.value?.trim(),price=document.getElementById('npPrice')?.value;
if(!n||!cat||!unit||!price){toast('Fill all required fields','e');return;}
try{await api('POST','/products',{name:n,category:cat,unit,price:parseFloat(price),description:document.getElementById('npDesc')?.value||'',imageUrl:document.getElementById('npImg')?.value||'',initialStock:parseInt(document.getElementById('npQty')?.value||0),gps:S.gps},true);toast('Product submitted for approval!','s');closeModal('addProdModal');}
catch(e){toast('Failed: '+e.message,'e');}
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ INIT โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
document.addEventListener('DOMContentLoaded',()=>{
fillCounties();
// Init step indicator
for(let i=1;i<=5;i++){
const d=document.getElementById('sd'+i);
if(d)d.style.cssText=i===1?'width:28px;height:28px;border-radius:50%;background:#f0b429;color:#0d1f0f;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;flex-shrink:0':'width:28px;height:28px;border-radius:50%;background:#e0ddd4;color:#6b6457;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;flex-shrink:0';
const l=i<5?document.getElementById('sl'+i):null;
if(l)l.style.cssText='flex:1;height:2px;background:#e0ddd4;margin:0 4px';
}
const si=document.getElementById('stepInd');if(si)si.style.cssText='display:flex;align-items:center;margin-bottom:18px';
});