A mobile-first approach to Window film installation: understanding the purpose behind the Scorpion Scan platform
Back to Tutorials
newsTutorial

A mobile-first approach to Window film installation: understanding the purpose behind the Scorpion Scan platform

April 13, 20261 views6 min read

Introduction

In the window film installation industry, businesses like Scorpion Coatings are leveraging mobile-first platforms to streamline operations and improve customer service. This tutorial will guide you through building a simplified version of a mobile-first operational platform using Python and Flask, similar to what might power the Scorpion Scan platform. You'll learn how to create a mobile-responsive interface for tracking installation jobs, managing customer data, and logging service activities.

Prerequisites

  • Basic understanding of Python programming
  • Python 3.7 or higher installed
  • Flask web framework knowledge
  • Basic HTML and CSS skills
  • SQLite database familiarity
  • Basic mobile responsiveness concepts

Step-by-Step Instructions

1. Setting Up Your Development Environment

1.1 Create Project Directory

First, create a new directory for your project and navigate to it:

mkdir scorpion_scan_platform
 cd scorpion_scan_platform

1.2 Initialize Virtual Environment

Create a virtual environment to isolate your project dependencies:

python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

1.3 Install Required Packages

Install Flask and other necessary packages:

pip install flask flask-sqlalchemy

Why: We're setting up a clean environment to avoid conflicts with other Python projects and installing the core packages needed for our mobile-first platform.

2. Creating the Flask Application Structure

2.1 Create Main Application File

Create a file called app.py with the following content:

from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///scorpion.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

# Define our data models

class Customer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    phone = db.Column(db.String(20), nullable=False)
    email = db.Column(db.String(100), nullable=True)
    address = db.Column(db.Text, nullable=False)

    def __repr__(self):
        return f''

class Job(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    customer_id = db.Column(db.Integer, db.ForeignKey('customer.id'), nullable=False)
    job_type = db.Column(db.String(100), nullable=False)
    status = db.Column(db.String(50), nullable=False, default='pending')
    created_at = db.Column(db.DateTime, nullable=False, default=db.func.current_timestamp())
    notes = db.Column(db.Text, nullable=True)

    customer = db.relationship('Customer', backref=db.backref('jobs', lazy=True))

    def __repr__(self):
        return f''

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(debug=True)

2.2 Create Templates Directory

Create a directory called templates in your project folder:

mkdir templates

Why: This structure separates your application logic from your presentation layer, following Flask best practices.

3. Designing Mobile-Responsive HTML Templates

3.1 Create Base Template

Create templates/base.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Scorpion Scan Platform</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container-fluid">
            <a class="navbar-brand" href="{{ url_for('index') }}">Scorpion Scan</a>
            <div class="navbar-nav">
                <a class="nav-link" href="{{ url_for('customers') }}">Customers</a>
                <a class="nav-link" href="{{ url_for('jobs') }}">Jobs</a>
            </div>
        </div>
    </nav>

    <div class="container mt-4">
        {% block content %}{% endblock %}
    </div>

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

3.2 Create Home Page Template

Create templates/index.html:

{% extends "base.html" %}

{% block content %}
<div class="row">
    <div class="col-md-12 text-center">
        <h1>Welcome to Scorpion Scan</h1>
        <p class="lead">Mobile-first platform for window film installation</p>
    </div>
</div>

<div class="row mt-4">
    <div class="col-md-6">
        <div class="card">
            <div class="card-body">
                <h5 class="card-title">Manage Customers</h5>
                <p class="card-text">Add and view customer information for installations.</p>
                <a href="{{ url_for('customers') }}" class="btn btn-primary">View Customers</a>
            </div>
        </div>
    </div>
    <div class="col-md-6">
        <div class="card">
            <div class="card-body">
                <h5 class="card-title">Track Jobs</h5>
                <p class="card-text">Monitor installation jobs and their status.</p>
                <a href="{{ url_for('jobs') }}" class="btn btn-primary">View Jobs</a>
            </div>
        </div>
    </div>
</div>
{% endblock %}

Why: Bootstrap CSS provides responsive design out-of-the-box, making our platform mobile-friendly without complex media queries.

4. Implementing Core Functionality

4.1 Add Customer Management Routes

Update your app.py with customer management routes:

@app.route('/customers')
def customers():
    customers = Customer.query.all()
    return render_template('customers.html', customers=customers)

@app.route('/customers/new', methods=['GET', 'POST'])
def new_customer():
    if request.method == 'POST':
        customer = Customer(
            name=request.form['name'],
            phone=request.form['phone'],
            email=request.form['email'],
            address=request.form['address']
        )
        db.session.add(customer)
        db.session.commit()
        return redirect(url_for('customers'))
    return render_template('new_customer.html')

4.2 Create Customer Templates

Create templates/customers.html:

{% extends "base.html" %}

{% block content %}
<h2>Customers</h2>
<a href="{{ url_for('new_customer') }}" class="btn btn-success mb-3">Add New Customer</a>

<div class="table-responsive">
    <table class="table table-striped">
        <thead>
            <tr>
                <th>Name</th>
                <th>Phone</th>
                <th>Email</th>
                <th>Address</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
            {% for customer in customers %}
            <tr>
                <td>{{ customer.name }}</td>
                <td>{{ customer.phone }}</td>
                <td>{{ customer.email }}</td>
                <td>{{ customer.address[:50] }}...</td>
                <td><a href="#" class="btn btn-sm btn-info">View</a></td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
</div>
{% endblock %}

4.3 Create New Customer Form

Create templates/new_customer.html:

{% extends "base.html" %}

{% block content %}
<h2>Add New Customer</h2>

<form method="POST" action="{{ url_for('new_customer') }}">
    <div class="mb-3">
        <label for="name" class="form-label">Name</label>
        <input type="text" class="form-control" id="name" name="name" required>
    </div>
    <div class="mb-3">
        <label for="phone" class="form-label">Phone</label>
        <input type="tel" class="form-control" id="phone" name="phone" required>
    </div>
    <div class="mb-3">
        <label for="email" class="form-label">Email</label>
        <input type="email" class="form-control" id="email" name="email">
    </div>
    <div class="mb-3">
        <label for="address" class="form-label">Address</label>
        <textarea class="form-control" id="address" name="address" rows="3" required></textarea>
    </div>
    <button type="submit" class="btn btn-primary">Save Customer</button>
    <a href="{{ url_for('customers') }}" class="btn btn-secondary">Cancel</a>
</form>
{% endblock %}

5. Adding Job Management

5.1 Implement Job Routes

Add job management routes to your app.py:

@app.route('/jobs')
def jobs():
    jobs = Job.query.join(Customer).order_by(Job.created_at.desc()).all()
    return render_template('jobs.html', jobs=jobs)

@app.route('/jobs/new', methods=['GET', 'POST'])
def new_job():
    customers = Customer.query.all()
    if request.method == 'POST':
        job = Job(
            customer_id=request.form['customer_id'],
            job_type=request.form['job_type'],
            status=request.form['status'],
            notes=request.form['notes']
        )
        db.session.add(job)
        db.session.commit()
        return redirect(url_for('jobs'))
    return render_template('new_job.html', customers=customers)

5.2 Create Job Templates

Create templates/jobs.html:

{% extends "base.html" %}

{% block content %}
<h2>Installation Jobs</h2>
<a href="{{ url_for('new_job') }}" class="btn btn-success mb-3">Add New Job</a>

<div class="table-responsive">
    <table class="table table-striped">
        <thead>
            <tr>
                <th>Customer</th>
                <th>Job Type</th>
                <th>Status</th>
                <th>Created</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
            {% for job in jobs %}
            <tr>
                <td>{{ job.customer.name }}</td>
                <td>{{ job.job_type }}</td>
                <td><span class="badge bg-{{ 'success' if job.status == 'completed' else 'warning' if job.status == 'in_progress' else 'secondary' }}">{{ job.status }}</span></td>
                <td>{{ job.created_at.strftime('%Y-%m-%d') }}</td>
                <td><a href="#" class="btn btn-sm btn-info">View</a></td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
</div>
{% endblock %}

5.3 Create New Job Form

Create templates/new_job.html:

{% extends "base.html" %}

{% block content %}
<h2>Add New Job</h2>

<form method="POST" action="{{ url_for('new_job') }}">
    <div class="mb-3">
        <label for="customer_id" class="form-label">Customer</label>
        <select class="form-control" id="customer_id" name="customer_id" required>
            {% for customer in customers %}
            <option value="{{ customer.id }}">{{ customer.name }}</option>
            {% endfor %}
        </select>
    </div>
    <div class="mb-3">
        <label for="job_type" class="form-label">Job Type</label>
        <input type="text" class="form-control" id="job_type" name="job_type" required>
    </div>
    <div class="mb-3">
        <label for="status" class="form-label">Status</label>
        <select class="form-control" id="status" name="status" required>
            <option value="pending">Pending</option>
            <option value="in_progress">In Progress</option>
            <option value="completed">Completed</option>
        </select>
    </div>
    <div class="mb-3">
        <label for="notes" class="form-label">Notes</label>
        <textarea class="form-control" id="notes" name="notes" rows="3"></textarea>
    </div>
    <button type="submit" class="btn btn-primary">Save Job</button>
    <a href="{{ url_for('jobs') }}" class="btn btn-secondary">Cancel</a>
</form>
{% endblock %}

6. Running Your Application

Run your application with:

python app.py

Visit http://localhost:5000 in your browser to see your mobile-friendly platform in action.

This implementation provides a foundation for a mobile-first platform that can be extended with features like:

  • Real-time status updates
  • Mobile app integration
  • Advanced reporting
  • User authentication
  • API endpoints for mobile apps

Remember to install required packages:

pip install flask flask-sqlalchemy

Source: TNW Neural

Related Articles