| |
| |
|
|
| |
| |
| |
| |
| window.TRADE_CATEGORIES = [ |
| { id: 'electrical', label: 'Electrical' }, |
| { id: 'plumbing', label: 'Plumbing' }, |
| { id: 'carpentry', label: 'Carpentry' }, |
| { id: 'painting', label: 'Painting' }, |
| { id: 'tiling', label: 'Tiling' }, |
| { id: 'building', label: 'Building' }, |
| { id: 'gardening', label: 'Gardening' }, |
| { id: 'cleaning', label: 'Cleaning' }, |
| { id: 'handyman', label: 'Handyman' }, |
| { id: 'other', label: 'Other' } |
| ]; |
|
|
| |
| window.TRADE_BY_ID = window.TRADE_CATEGORIES.reduce((acc, t) => { |
| acc[t.id] = t; |
| return acc; |
| }, {}); |
|
|
| window.tradeLabel = function tradeLabel(id) { |
| const key = String(id || '').trim(); |
| return (window.TRADE_BY_ID && window.TRADE_BY_ID[key]) ? window.TRADE_BY_ID[key].label : (key || 'Other'); |
| }; |
|
|
| window.normalizeTradeIds = function normalizeTradeIds(input) { |
| |
| const raw = Array.isArray(input) |
| ? input |
| : (typeof input === 'string' ? input.split(',') : [input]); |
|
|
| const out = []; |
| raw |
| .map(v => String(v || '').trim()) |
| .filter(Boolean) |
| .forEach((v) => { |
| const norm = v.toLowerCase(); |
| |
| const byLabel = window.TRADE_CATEGORIES.find(t => t.label.toLowerCase() === norm); |
| const id = byLabel ? byLabel.id : norm; |
| if (window.TRADE_BY_ID[id] && !out.includes(id)) out.push(id); |
| }); |
|
|
| return out.length ? out : ['other']; |
| }; |
|
|
| window.inferTradeIdsFromText = function inferTradeIdsFromText(text) { |
| const t = String(text || '').toLowerCase(); |
| const ids = []; |
| const push = (id) => { if (window.TRADE_BY_ID[id] && !ids.includes(id)) ids.push(id); }; |
|
|
| if (t.includes('electr')) push('electrical'); |
| if (t.includes('plumb')) push('plumbing'); |
| if (t.includes('carpent') || t.includes('fence') || t.includes('deck')) push('carpentry'); |
| if (t.includes('paint')) push('painting'); |
| if (t.includes('tile')) push('tiling'); |
| if (t.includes('build') || t.includes('reno') || t.includes('contractor')) push('building'); |
| if (t.includes('landscap') || t.includes('garden')) push('gardening'); |
| if (t.includes('clean')) push('cleaning'); |
| if (t.includes('handy') || t.includes('repairs') || t.includes('fix')) push('handyman'); |
|
|
| return ids.length ? ids : ['other']; |
| }; |
|
|
| |
| |
| window.makeDemoReviews = function makeDemoReviews(totalCount, avgRating, reviewerRoleLabel) { |
| const total = Math.max(0, Number(totalCount || 0)); |
| const avg = Math.max(0, Math.min(5, Number(avgRating || 0))); |
| const visible = Math.min(total, 8); |
| const role = reviewerRoleLabel || 'User'; |
| const templates = [ |
| 'Clear communication and smooth process.', |
| 'Arrived on time and kept things tidy.', |
| 'Scope was clear and payment was prompt.', |
| 'Good workmanship and easy to work with.', |
| 'Would work together again.', |
| 'Professional, responsive, and straightforward.', |
| 'Job matched the description and expectations.', |
| 'Handled changes in scope reasonably.' |
| ]; |
| const out = []; |
| for (let i = 0; i < visible; i++) { |
| |
| const jitter = (i % 3) - 1; |
| const stars = Math.max(1, Math.min(5, Math.round(avg + jitter))); |
| out.push({ |
| stars, |
| byRole: role, |
| text: templates[i % templates.length], |
| ts: Date.now() - (i + 1) * 86400000 * 14 |
| }); |
| } |
| return out; |
| }; |
|
|
| |
| |
| |
| |
|
|
| window.CURRENT_USER_DEFAULT = { |
| id: "me", |
| role: "dual", |
| displayName: "Jayden", |
| avatar: "https://static.photos/people/320x240/301", |
| avatarDataUrl: "", |
| location: { suburb: "Pakenham", state: "VIC", postcode: "3810" }, |
| contact: { phone: "", email: "" }, |
| auth: { provider: "local", uid: null }, |
| tradie: { |
| |
| trades: ['building'] |
| }, |
| privacy: { |
| showLocation: true, |
| addressRule: "afterAccepted" |
| }, |
| verification: { |
| verified: false, |
| abnFull: "", |
| licenseFull: "" |
| } |
| }; |
|
|
| window.TRADIES = { |
| |
|
|
| liam: { |
| name: "Liam Thompson", |
| trade: "Licensed Electrician", |
| location: "Melbourne, VIC", |
| rating: "4.8", |
| |
| reviewCount: 3, |
| verified: true, |
| image: "https://static.photos/people/320x240/302", |
| conversationId: "liam-thompson", |
| about: |
| "Reliable sparky for residential + light commercial. Safety-first, tidy work, clear quotes." |
| }, |
| olivia: { |
| name: "Olivia Chen", |
| trade: "Plumber", |
| location: "Pakenham, VIC", |
| rating: "4.7", |
| reviewCount: 2, |
| verified: true, |
| image: "https://static.photos/people/320x240/303", |
| conversationId: "olivia-chen", |
| about: |
| "Blocked drains, hot water systems, leaking taps. Fast response and upfront pricing." |
| }, |
| noah: { |
| name: "Noah Williams", |
| trade: "Carpenter", |
| location: "Dandenong, VIC", |
| rating: "4.6", |
| reviewCount: 0, |
| verified: false, |
| image: "https://static.photos/people/320x240/304", |
| conversationId: "noah-williams", |
| about: |
| "Decks, pergolas, framing, small renovations. Clean finish and good communication." |
| }, |
|
|
| |
| mark: { |
| name: "Mark Johnson", |
| trade: "Licensed Plumber", |
| location: "Sydney, NSW", |
| rating: "4.9", |
| reviewCount: 18, |
| verified: true, |
| image: "https://static.photos/construction/320x240/201", |
| conversationId: "mark-johnson", |
| about: |
| "Residential + commercial plumbing. Fast response, clean work, transparent pricing." |
| }, |
| sarah: { |
| name: "Sarah Chen", |
| trade: "Master Electrician", |
| location: "Melbourne, VIC", |
| rating: "4.7", |
| reviewCount: 14, |
| verified: true, |
| image: "https://static.photos/technology/320x240/202", |
| conversationId: "sarah-chen", |
| about: |
| "Switchboards, lighting, fault-finding, compliance work. Licensed and punctual." |
| }, |
| david: { |
| name: "David Wilson", |
| trade: "Master Carpenter", |
| location: "Brisbane, QLD", |
| rating: "5.0", |
| reviewCount: 9, |
| verified: true, |
| image: "https://static.photos/people/320x240/304", |
| conversationId: "david-wilson", |
| about: |
| "Decking, framing, pergolas, renos. High-end finish, reliable timelines." |
| }, |
| lisa: { |
| name: "Lisa Brown", |
| trade: "Professional Painter", |
| location: "Perth, WA", |
| rating: "4.6", |
| reviewCount: 7, |
| verified: true, |
| image: "https://static.photos/people/320x240/305", |
| conversationId: "lisa-brown", |
| about: |
| "Interior/exterior painting, patch + prep, clean lines. Protective masking + tidy handover." |
| }, |
| james: { |
| name: "James Taylor", |
| trade: "Landscape Gardener", |
| location: "Adelaide, SA", |
| rating: "4.9", |
| reviewCount: 11, |
| verified: true, |
| image: "https://static.photos/people/320x240/306", |
| conversationId: "james-taylor", |
| about: |
| "Garden cleanups, turf, planting, edging, ongoing maintenance. Efficient and consistent." |
| } |
| }; |
|
|
| |
| |
| window.inferTradeIdsFromText = function inferTradeIdsFromText(text) { |
| const t = String(text || '').toLowerCase(); |
| const out = new Set(); |
| if (t.includes('electric')) out.add('electrical'); |
| if (t.includes('plumb')) out.add('plumbing'); |
| if (t.includes('carpent') || t.includes('joiner')) out.add('carpentry'); |
| if (t.includes('paint') || t.includes('decor')) out.add('painting'); |
| if (t.includes('tile')) out.add('tiling'); |
| if (t.includes('build') || t.includes('reno') || t.includes('contractor')) out.add('building'); |
| if (t.includes('garden') || t.includes('landscape')) out.add('gardening'); |
| if (t.includes('clean')) out.add('cleaning'); |
| if (t.includes('handy')) out.add('handyman'); |
| if (out.size === 0) out.add('other'); |
| return Array.from(out); |
| }; |
|
|
| Object.keys(window.TRADIES || {}).forEach((id) => { |
| const t = window.TRADIES[id]; |
| if (!t) return; |
| if (!Array.isArray(t.trades) || t.trades.length === 0) { |
| t.trades = window.inferTradeIdsFromText(t.trade); |
| } |
| if (!Array.isArray(t.reviews)) { |
| t.reviews = window.makeDemoReviews(t.reviewCount, parseFloat(t.rating || '0'), 'Customer'); |
| } |
| }); |
|
|
| window.CUSTOMERS = { |
| |
| "michael-roberts": { |
| name: "Michael Roberts", |
| typeLabel: "Homeowner", |
| typeColor: "bg-blue-500", |
| location: "Sydney, NSW", |
| tagline: "Member since 2022", |
| rating: "4.3", |
| reviewCount: 12, |
| image: "https://static.photos/people/320x240/301", |
| conversationId: "michael-roberts", |
| about: |
| "Homeowner looking for various home services. Has completed 8 projects and values clear communication and tidy work." |
| }, |
| "sarah-johnson": { |
| name: "Sarah Johnson", |
| typeLabel: "Business", |
| typeColor: "bg-purple-500", |
| location: "Melbourne, VIC", |
| tagline: "Property Manager", |
| rating: "4.8", |
| reviewCount: 26, |
| image: "https://static.photos/office/320x240/302", |
| conversationId: "sarah-johnson", |
| about: |
| "Property manager coordinating ongoing works. Prefers quotes with clear scope and reliable scheduling." |
| }, |
| "david-chen": { |
| name: "David Chen", |
| typeLabel: "Homeowner", |
| typeColor: "bg-blue-500", |
| location: "Brisbane, QLD", |
| tagline: "Member since 2023", |
| rating: "4.5", |
| reviewCount: 8, |
| image: "https://static.photos/people/320x240/303", |
| conversationId: "david-chen", |
| about: |
| "Planning home improvement projects (deck build). Looking for a tradie who can guide material choices and timelines." |
| }, |
| "lisa-williams": { |
| name: "Lisa Williams", |
| typeLabel: "Real Estate", |
| typeColor: "bg-green-500", |
| location: "Perth, WA", |
| tagline: "Real Estate Agency", |
| rating: "4.9", |
| reviewCount: 63, |
| image: "https://static.photos/workspace/320x240/304", |
| conversationId: "lisa-williams", |
| about: |
| "Real estate agency managing multiple properties. Regular work for reliable tradies. Prompt payment." |
| }, |
| "robert-kim": { |
| name: "Robert Kim", |
| typeLabel: "Homeowner", |
| typeColor: "bg-blue-500", |
| location: "Adelaide, SA", |
| tagline: "Member since 2021", |
| rating: "4.2", |
| reviewCount: 5, |
| image: "https://static.photos/people/320x240/305", |
| conversationId: "robert-kim", |
| about: |
| "Occasional projects and emergency repairs. Values quick response and quality work." |
| } |
| }; |
|
|
| Object.keys(window.CUSTOMERS || {}).forEach((id) => { |
| const c = window.CUSTOMERS[id]; |
| if (!c) return; |
| if (!Array.isArray(c.reviews)) { |
| c.reviews = window.makeDemoReviews(c.reviewCount, parseFloat(c.rating || '0'), 'Tradie'); |
| } |
| }); |
|
|
| |
| (function(){ |
| try { |
| const raw = localStorage.getItem("athCurrentUser"); |
| const u = raw ? JSON.parse(raw) : window.CURRENT_USER_DEFAULT; |
| const role = (u && u.role) ? u.role : (window.CURRENT_USER_DEFAULT.role || "dual"); |
| const loc = `${(u.location?.suburb||"")} ${(u.location?.state||"")}`.trim(); |
| const location = loc.replace(/\s+/g, " ").replace(/""/g, ""); |
| const displayLoc = `${u.location?.suburb || ""}, ${u.location?.state || ""}`.replace("undefined","").replace(" ,","").trim(); |
|
|
| const enableCustomer = (role === "customer" || role === "dual"); |
| const enableTradie = (role === "tradie" || role === "dual"); |
|
|
| if (enableTradie) { |
| const tradeIds = Array.isArray(u.tradie?.trades) && u.tradie.trades.length |
| ? u.tradie.trades |
| : (u.tradie?.trade ? window.inferTradeIdsFromText(u.tradie.trade) : window.inferTradeIdsFromText('builder')); |
| const tradeLabelLine = tradeIds.map(window.tradeLabel).join(' • '); |
| window.TRADIES.me = { |
| name: u.displayName || "Me", |
| trade: tradeLabelLine || "General Contractor", |
| trades: tradeIds, |
| location: displayLoc, |
| rating: "—", |
| reviewCount: 0, |
| verified: !!u.verification?.verified, |
| image: u.avatarDataUrl || u.avatar || "https://static.photos/people/320x240/301", |
| conversationId: "me", |
| about: "This is your public tradie profile preview." |
| }; |
| } else { |
| delete window.TRADIES.me; |
| } |
|
|
| if (enableCustomer) { |
| window.CUSTOMERS.me = { |
| name: u.displayName || "Me", |
| typeLabel: "Customer", |
| typeColor: "bg-blue-500", |
| location: displayLoc, |
| tagline: "Your account", |
| rating: "—", |
| reviewCount: 0, |
| image: u.avatarDataUrl || u.avatar || "https://static.photos/people/320x240/301", |
| conversationId: "me", |
| about: "This is your public customer profile preview." |
| }; |
| } else { |
| delete window.CUSTOMERS.me; |
| } |
| } catch(e) { } |
| })(); |
|
|
|
|
| |
|
|
| |
| |
| window.CONVERSATIONS = { |
| "michael-roberts": { |
| name: "Michael Roberts", |
| meta: "Homeowner • Sydney, NSW", |
| avatar: "https://static.photos/people/320x240/301", |
| avatarDataUrl: "", |
| online: true, |
| tag: { label: "Bathroom Renovation", color: "bg-blue-100 text-blue-800" }, |
| messages: [ |
| { from: "them", time: "10:15 AM", ts: 1768676100000, text: "When can you start?" }, |
| { from: "me", time: "10:24 AM", ts: 1768676640000, text: "Next Monday works." } |
| ] |
| }, |
| "sarah-johnson": { |
| name: "Sarah Johnson", |
| meta: "Office Manager • Melbourne, VIC", |
| avatar: "https://static.photos/office/320x240/302", |
| online: true, |
| tag: { label: "Office Electrical", color: "bg-purple-100 text-purple-800" }, |
| messages: [ |
| { from: "them", time: "Yesterday", ts: 1768590000000, text: "I've attached the electrical schematics for the office upgrade project." } |
| ] |
| }, |
| "david-chen": { |
| name: "David Chen", |
| meta: "Homeowner • Brisbane, QLD", |
| avatar: "https://static.photos/people/320x240/303", |
| online: false, |
| tag: { label: "Deck Construction", color: "bg-green-100 text-green-800" }, |
| messages: [ |
| { from: "them", time: "2 days ago", ts: 1768503600000, text: "The timber has arrived. Are you still available to start next Monday?" } |
| ] |
| }, |
| "lisa-williams": { |
| name: "Lisa Williams", |
| meta: "Real Estate • Perth, WA", |
| avatar: "https://static.photos/workspace/320x240/304", |
| online: true, |
| tag: { label: "Maintenance Contract", color: "bg-blue-100 text-blue-800" }, |
| messages: [ |
| { from: "them", time: "3 days ago", ts: 1768417200000, text: "Can you provide a quote for the monthly maintenance contract?" } |
| ] |
| }, |
| "robert-kim": { |
| name: "Robert Kim", |
| meta: "Homeowner • Adelaide, SA", |
| avatar: "https://static.photos/people/320x240/305", |
| online: false, |
| tag: { label: "Emergency Callout", color: "bg-red-100 text-red-800" }, |
| messages: [ |
| { from: "them", time: "1 week ago", ts: 1768068000000, text: "We have a leaking pipe under the sink — can you come ASAP?" } |
| ] |
| }, |
|
|
| |
| "mark-johnson": { |
| name: "Mark Johnson", |
| meta: "Licensed Plumber • Sydney, NSW", |
| avatar: "https://static.photos/construction/320x240/201", |
| online: true, |
| tag: { label: "Plumbing", color: "bg-blue-100 text-blue-800" }, |
| messages: [ |
| { from: "them", time: "2 weeks ago", ts: 1767463200000, text: "Thanks for the great work last time — can you quote another job?" } |
| ] |
| }, |
| "sarah-chen": { |
| name: "Sarah Chen", |
| meta: "Master Electrician • Melbourne, VIC", |
| avatar: "https://static.photos/technology/320x240/202", |
| online: false, |
| tag: { label: "Electrical Inspection", color: "bg-purple-100 text-purple-800" }, |
| messages: [ |
| { from: "them", time: "3 weeks ago", ts: 1766858400000, text: "When can you schedule the electrical inspection?" } |
| ] |
| }, |
| "liam-thompson": { |
| name: "Liam Thompson", |
| meta: "Licensed Electrician • Melbourne, VIC", |
| avatar: "https://static.photos/people/320x240/302", |
| online: true, |
| tag: { label: "Switchboard Upgrade", color: "bg-purple-100 text-purple-800" }, |
| messages: [ |
| { from: "them", time: "Now", ts: 1768677000000, text: "Hey mate, can you do a quick quote for a switchboard upgrade?" }, |
| { from: "me", time: "Now", ts: 1768677060000, text: "Yep — send photos of the board and your suburb and I'll price it." } |
| ] |
| }, |
| "olivia-chen": { |
| name: "Olivia Chen", |
| meta: "Plumber • Pakenham, VIC", |
| avatar: "https://static.photos/people/320x240/303", |
| online: true, |
| tag: { label: "Hot Water", color: "bg-blue-100 text-blue-800" }, |
| messages: [ |
| { from: "them", time: "Now", ts: 1768677300000, text: "Hot water system playing up — can you take a look tomorrow?" } |
| ] |
| }, |
| "noah-williams": { |
| name: "Noah Williams", |
| meta: "Carpenter • Dandenong, VIC", |
| avatar: "https://static.photos/people/320x240/304", |
| online: false, |
| tag: { label: "Pergola", color: "bg-green-100 text-green-800" }, |
| messages: [ |
| { from: "them", time: "Yesterday", ts: 1768593000000, text: "Looking at a small pergola — what do you need from me to quote?" } |
| ] |
| }, |
| "david-wilson": { |
| name: "David Wilson", |
| meta: "Master Carpenter • Brisbane, QLD", |
| avatar: "https://static.photos/people/320x240/304", |
| online: false, |
| tag: { label: "Decking", color: "bg-green-100 text-green-800" }, |
| messages: [ |
| { from: "them", time: "Last week", ts: 1768071600000, text: "Thanks again — the decking came up unreal." } |
| ] |
| }, |
| "lisa-brown": { |
| name: "Lisa Brown", |
| meta: "Professional Painter • Perth, WA", |
| avatar: "https://static.photos/people/320x240/305", |
| online: true, |
| tag: { label: "Painting", color: "bg-yellow-100 text-yellow-800" }, |
| messages: [ |
| { from: "them", time: "2 days ago", ts: 1768507200000, text: "Can you squeeze in a bedroom repaint next week?" } |
| ] |
| }, |
| "james-taylor": { |
| name: "James Taylor", |
| meta: "Landscape Gardener • Adelaide, SA", |
| avatar: "https://static.photos/people/320x240/306", |
| online: true, |
| tag: { label: "Garden Cleanup", color: "bg-green-100 text-green-800" }, |
| messages: [ |
| { from: "them", time: "3 days ago", ts: 1768420800000, text: "Need a quick garden cleanup before an inspection — available this weekend?" } |
| ] |
| } |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| |
| window.JOBS = [ |
| { |
| id: 'job-bathroom-reno-001', |
| title: 'Bathroom Renovation', |
| description: 'Full bathroom remodel including tiling, plumbing, and electrical work. Need completion within 2–3 weeks.', |
| categories: ['plumbing', 'electrical', 'tiling'], |
| location: 'Sydney, NSW', |
| state: 'NSW', |
| budgetMin: 8000, |
| budgetMax: 12000, |
| timeline: '2–3 weeks', |
| urgency: 'urgent', |
| type: 'contract', |
| quotes: 3, |
| customerId: 'michael-roberts', |
| postedAt: '2026-01-18T07:15:00.000Z', |
| status: 'open' |
| }, |
| { |
| id: 'job-office-electrical-002', |
| title: 'Office Electrical Upgrade', |
| description: 'Commercial electrical work for 10 office units. LED lighting installation and power point upgrades. Specs available.', |
| categories: ['electrical'], |
| location: 'Melbourne, VIC', |
| state: 'VIC', |
| budgetMin: 15000, |
| budgetMax: 25000, |
| timeline: 'Flexible', |
| urgency: 'week', |
| type: 'contract', |
| quotes: 8, |
| customerId: 'sarah-johnson', |
| postedAt: '2026-01-17T03:00:00.000Z', |
| status: 'open' |
| }, |
| { |
| id: 'job-deck-003', |
| title: 'Deck Construction (6x4m)', |
| description: 'Build a 6x4m timber deck with stairs and railing. Materials provided by customer. Start in 3–4 weeks.', |
| categories: ['carpentry'], |
| location: 'Brisbane, QLD', |
| state: 'QLD', |
| budgetMin: 3500, |
| budgetMax: 5000, |
| timeline: '2 weeks', |
| urgency: 'flexible', |
| type: 'one-off', |
| quotes: 12, |
| customerId: 'david-chen', |
| postedAt: '2026-01-16T01:30:00.000Z', |
| status: 'open' |
| }, |
| { |
| id: 'job-interior-paint-004', |
| title: 'Interior repaint (3 bedrooms)', |
| description: 'Prep + paint 3 bedrooms. Walls + trims. Customer to supply paint if recommended. Prefer tidy & quick turnaround.', |
| categories: ['painting'], |
| location: 'Perth, WA', |
| state: 'WA', |
| budgetMin: 900, |
| budgetMax: 1800, |
| timeline: '3–5 days', |
| urgency: 'week', |
| type: 'one-off', |
| quotes: 4, |
| customerId: 'lisa-williams', |
| postedAt: '2026-01-15T05:00:00.000Z', |
| status: 'open' |
| }, |
| { |
| id: 'job-garden-cleanup-005', |
| title: 'Garden cleanup before inspection', |
| description: 'Mow, edge, weed, green waste removal. Need done this weekend before property inspection.', |
| categories: ['gardening'], |
| location: 'Adelaide, SA', |
| state: 'SA', |
| budgetMin: 250, |
| budgetMax: 450, |
| timeline: '1 day', |
| urgency: 'urgent', |
| type: 'one-off', |
| quotes: 2, |
| customerId: 'robert-kim', |
| postedAt: '2026-01-18T00:20:00.000Z', |
| status: 'open' |
| }, |
| { |
| id: 'job-hot-water-006', |
| title: 'Hot water system replacement', |
| description: 'Existing unit failing. Need supply + install of suitable replacement, and disposal of old unit.', |
| categories: ['plumbing'], |
| location: 'Pakenham, VIC', |
| state: 'VIC', |
| budgetMin: 1200, |
| budgetMax: 2500, |
| timeline: '1–2 days', |
| urgency: 'urgent', |
| type: 'one-off', |
| quotes: 5, |
| customerId: 'michael-roberts', |
| postedAt: '2026-01-17T23:10:00.000Z', |
| status: 'open' |
| }, |
| { |
| id: 'job-lawn-ongoing-007', |
| title: 'Ongoing lawn maintenance (fortnightly)', |
| description: 'Small front + backyard. Fortnightly mow/edge and seasonal tidy-ups.', |
| categories: ['gardening'], |
| location: 'Melbourne, VIC', |
| state: 'VIC', |
| budgetMin: 80, |
| budgetMax: 140, |
| timeline: 'Ongoing', |
| urgency: 'flexible', |
| type: 'ongoing', |
| quotes: 6, |
| customerId: 'sarah-johnson', |
| postedAt: '2026-01-14T02:00:00.000Z', |
| status: 'open' |
| }, |
| { |
| id: 'job-bond-clean-008', |
| title: 'Bond clean (2 bed unit)', |
| description: 'End-of-lease clean. Kitchen, bathroom, floors, windows. Must be completed by Friday.', |
| categories: ['cleaning'], |
| location: 'Sydney, NSW', |
| state: 'NSW', |
| budgetMin: 300, |
| budgetMax: 550, |
| timeline: '1 day', |
| urgency: 'week', |
| type: 'one-off', |
| quotes: 9, |
| customerId: 'lisa-williams', |
| postedAt: '2026-01-13T10:30:00.000Z', |
| status: 'open' |
| }, |
| { |
| id: 'job-handy-009', |
| title: 'Fix doors + replace handles', |
| description: '3 internal doors sticking. Replace 2 handles and align hinges. Quick handyman job.', |
| categories: ['handyman'], |
| location: 'Brisbane, QLD', |
| state: 'QLD', |
| budgetMin: 180, |
| budgetMax: 350, |
| timeline: 'Half day', |
| urgency: 'flexible', |
| type: 'one-off', |
| quotes: 1, |
| customerId: 'david-chen', |
| postedAt: '2026-01-12T00:15:00.000Z', |
| status: 'open' |
| }, |
| { |
| id: 'job-switchboard-010', |
| title: 'Switchboard safety check', |
| description: 'Need a licensed electrician to inspect switchboard, test RCDs, and provide compliance note.', |
| categories: ['electrical'], |
| location: 'Adelaide, SA', |
| state: 'SA', |
| budgetMin: 220, |
| budgetMax: 420, |
| timeline: '1–2 hours', |
| urgency: 'week', |
| type: 'one-off', |
| quotes: 7, |
| customerId: 'robert-kim', |
| postedAt: '2026-01-11T04:45:00.000Z', |
| status: 'open' |
| }, |
| { |
| id: 'job-fence-011', |
| title: 'Replace side fence (approx. 18m)', |
| description: 'Old timber fence needs replacement. Prefer treated pine. Please include removal of old fence and materials.', |
| categories: ['carpentry', 'building'], |
| location: 'Perth, WA', |
| state: 'WA', |
| budgetMin: 4000, |
| budgetMax: 6500, |
| timeline: '1 week', |
| urgency: 'flexible', |
| type: 'contract', |
| quotes: 3, |
| customerId: 'lisa-williams', |
| postedAt: '2026-01-10T09:00:00.000Z', |
| status: 'open' |
| }, |
| { |
| id: 'job-kitchen-tap-012', |
| title: 'Kitchen tap leaking', |
| description: 'Tap is dripping constantly. Might need new mixer. Accessible under-sink plumbing.', |
| categories: ['plumbing'], |
| location: 'Melbourne, VIC', |
| state: 'VIC', |
| budgetMin: 150, |
| budgetMax: 380, |
| timeline: '1–2 hours', |
| urgency: 'urgent', |
| type: 'one-off', |
| quotes: 2, |
| customerId: 'sarah-johnson', |
| postedAt: '2026-01-18T02:40:00.000Z', |
| status: 'open' |
| } |
| ]; |
|
|