To everyone who told me, "Someone needs to make it easier to find a plow guy"... I finally did it! 🚜 After months of tweaking, the SnowSOS prototype is live and ready for testing. No seasonal contracts, no frantic phone calls—just neighbor helping neighbor. Whether you need a pro driver or the "kid next door" to shovel the walk, it's all here. I need my Minnesota friends to help me test this out during the next snowfall. Click the link in my bio to try the prototype! #SnowSOS #MNRealEstate #WinterTech #BetaLaunch
Version 2.0
import React, { useState, useEffect, useCallback } from ‘react’;
import { initializeApp } from ‘firebase/app’;
import { getAuth, signInAnonymously, signInWithCustomToken, onAuthStateChanged } from ‘firebase/auth’;
import {
getFirestore,
collection,
doc,
addDoc,
updateDoc,
onSnapshot,
query,
where,
serverTimestamp,
setLogLevel
} from ‘firebase/firestore’;
// CORRECTED: Icons are imported by their name, not prefixed with ‘Lu’
import { Snowflake, MapPin, User, Truck, Home, ClipboardList, CheckCircle, Loader2, Trash2, AlertTriangle } from ‘lucide-react’; // — Global Variable Definitions —
// These variables are provided by the Canvas environment.
const appId = typeof __app_id !== ‘undefined’ ? __app_id : ‘default-app-id’;
const firebaseConfig = typeof __firebase_config !== ‘undefined’ ? JSON.parse(__firebase_config) : {};
// FIXED: Changed __initialAuthToken to __initial_auth_token to prevent ReferenceError
const initialAuthToken = typeof __initial_auth_token !== ‘undefined’ ? __initial_auth_token : null; // Set Firestore log level for debugging (optional)
setLogLevel(‘error’); // Set to ‘debug’ if troubleshooting // Initialize Firebase services outside the component to prevent re-initialization
let app;
let db;
let auth; try {
app = initializeApp(firebaseConfig);
db = getFirestore(app);
auth = getAuth(app);
} catch (error) {
console.error(“Firebase initialization failed:”, error);
// Use dummy functions if initialization fails
app = null;
db = null;
auth = null;
} // Collection path for public data (shared between all users)
const PUBLIC_JOBS_COLLECTION_PATH = `/artifacts/${appId}/public/data/jobs`; /**
* Utility function to format the user ID for display.
* @param {string} uid The full user ID string.
* @returns {string} The shortened, displayable ID.
*/
const formatUserId = (uid) => uid ? `${uid.substring(0, 4)}…${uid.substring(uid.length – 4)}` : ‘N/A’; const JobCard = ({ job, isOperator, currentUserId, onClaim, onComplete }) => {
const isClaimedByMe = job.operatorId === currentUserId;
const isMyJob = job.homeownerId === currentUserId; // Define colors and icons based on status
let statusClass = ”;
let statusText = ”;
let statusIcon = null; if (job.status === ‘Open’) {
statusClass = ‘bg-green-100 text-green-700 border-green-300’;
statusText = ‘Open for Claim’;
statusIcon = ;
} else if (job.status === ‘Claimed’) {
statusClass = ‘bg-yellow-100 text-yellow-700 border-yellow-300’;
statusText = isClaimedByMe ? ‘Claimed by Me’ : `Claimed by ${formatUserId(job.claimedByUserId)}`;
statusIcon = ;
} else if (job.status === ‘Completed’) {
statusClass = ‘bg-blue-100 text-blue-700 border-blue-300’;
statusText = ‘Completed’;
statusIcon = ;
}
// Determine service type styling – UPDATED to handle ‘Salt’
let typeClass = ”;
switch (job.serviceType) {
case ‘Plow’:
typeClass = ‘bg-indigo-600 text-white’;
break;
case ‘Shovel’:
typeClass = ‘bg-orange-600 text-white’;
break;
case ‘Salt’:
typeClass = ‘bg-teal-600 text-white’; // New color for Salting
break;
default:
typeClass = ‘bg-gray-500 text-white’;
break;
} // Determine button visibility and text
let actionButton = null; if (isOperator) {
if (job.status === ‘Open’) {
actionButton = ( );
} else if (job.status === ‘Claimed’ && isClaimedByMe) {
actionButton = ( );
}
} return (
Major Update! Introducing Role-Based Features, Google Sign-In, and Live Maps
We are thrilled to announce a substantial overhaul of the SnowSOS platform, focused entirely on enhancing security, streamlining workflows, and improving the efficiency of connecting homeowners and plow drivers across Central Minnesota.
The new features are live today. Here’s a detailed breakdown of what’s new and what you need to know when you sign in:
To ensure a safer and more organized experience, every user is now required to declare their primary function upon their first login.
Google Sign-In is Now Required
We have retired the old anonymous login methods in favor of secure Google Authentication. This standard practice enhances the integrity of the platform and simplifies your access.
Define Your Role: Homeowner vs. Driver
Upon signing in for the first time, you will be prompted to select one of two permanent roles:
Role
Menu Access
Key Features
🏡 Homeowner
Request Form is visible.
Post Jobs and Manage Your Requests (Edit/Delete pending jobs). Access the new Rating System to review completed driver performance.
🚜 Plow Driver
Request Form is hidden.
Browse All Pending Jobs and instantly Confirm or Cancel a job. Access your new Driver Profile to track ratings and history.
2. Real-Time Mapping and Location Tools
We have upgraded our mapping infrastructure to use Google Maps, providing superior address accuracy, navigation, and distance calculations.
Geocoding & Accuracy: All posted job addresses are now accurately geocoded, ensuring precise marker placement on the map.
Distance Calculation: When viewing a job on the map, you can use the “Find Me” button to pinpoint your current location. The system will then calculate and display the estimated travel time and distance from your location to the job site, giving drivers immediate decision-making power.
Targeted Filtering: You can now instantly filter the map and the job list by the Area Selector (e.g., “Annandale”) and by Service Type (Driveway, Salting, etc.) to quickly find relevant work or requests.
3. Improved Job Management and Driver Profiles
Fix for Posting Hang & Photo Upload
We’ve resolved the previous issue where posting a request sometimes appeared to “hang.” The app now features robust error handling and confirmation, along with fully functional Cloud Storage integration for reliably uploading job site photos.
Driver Rating System (New!)
Drivers can now build a professional profile:
Driver Profile: Drivers have a dedicated profile showing their average rating and job history.
Homeowner Feedback: Once a job is marked as “Completed” by the driver, the homeowner who posted the request will see a prompt to Rate the Driver (1-5 stars), contributing to their overall performance score visible to the entire community.
We believe these updates mark a significant step forward in making SnowSOS the definitive platform for winter services!