Volver a proyectos
Web
1 min de lectura

Plataforma para la Seguridad en el Tránsito de Puerto Rico

Por Jeferson Heredia
13 de marzo de 2025
Webflow
Migración Web
Diseño UI/UX
Sitio Gubernamental
Plataforma para la Seguridad en el Tránsito de Puerto Rico

Descripción

Lideré la migración completa del sitio web oficial de la Comisión para la Seguridad en el Tránsito de Puerto Rico (CST) desde WordPress a la plataforma Webflow, transformando la presencia digital de esta importante institución gubernamental.

El proyecto implicó un rediseño completo de la arquitectura de información y la experiencia de usuario, manteniendo la identidad visual institucional mientras se modernizaba la interfaz para hacerla más accesible e intuitiva para los ciudadanos.

Uno de los principales objetivos fue optimizar el rendimiento del sitio y mejorar la accesibilidad, asegurando que todos los ciudadanos, independientemente de sus capacidades, pudieran acceder a información crítica sobre seguridad vial. Implementé las mejores prácticas de SEO para aumentar la visibilidad del sitio y facilitar que los usuarios encuentren rápidamente la información que necesitan.

Tecnologías Utilizadas

Webflow

Plataforma principal para el desarrollo y diseño del nuevo sitio

HTML5/CSS3

Estructura y estilos personalizados para componentes específicos

JavaScript

Funcionalidades interactivas y mejoras de experiencia de usuario

Figma

Diseño de wireframes y prototipos de alta fidelidad

Optimización SEO

Implementación de mejores prácticas para motores de búsqueda

Accesibilidad Web

Cumplimiento de estándares WCAG para accesibilidad

Desafíos

Migración de contenido extenso

El sitio contaba con una gran cantidad de contenido acumulado durante años, incluyendo documentos legales, estadísticas y recursos educativos que debían ser migrados sin pérdida de información.

Requisitos gubernamentales

Cumplir con los estrictos requisitos de seguridad, accesibilidad y transparencia exigidos para sitios web gubernamentales oficiales.

Optimización de rendimiento

El sitio anterior sufría de tiempos de carga lentos y problemas de rendimiento que afectaban la experiencia del usuario, especialmente en dispositivos móviles y conexiones lentas.

Soluciones

Estrategia de migración por fases

Implementé una migración gradual que permitió validar cada sección antes de pasar a la siguiente, minimizando el riesgo de pérdida de datos y asegurando la integridad del contenido.

Arquitectura de información optimizada

Rediseñé la estructura del sitio para mejorar la navegación y facilitar el acceso a la información más buscada por los ciudadanos, basándome en análisis de datos de uso.

Diseño responsivo y accesible

Desarrollé una interfaz completamente responsiva que cumple con los estándares WCAG 2.1 de accesibilidad, asegurando que el sitio sea utilizable por personas con diversas capacidades.

Galería

Página principal del sitio web de la CST Puerto Rico

Página principal del sitio web de la CST Puerto Rico

Versión móvil optimizada del sitio

Versión móvil optimizada del sitio

Sección de servicios con navegación mejorada

Sección de servicios con navegación mejorada

Ejemplo de Código

user_manager.py

from django.db import models
from django.contrib.auth.models import User
from django.utils.text import slugify
from django.urls import reverse
import uuid

class Category(models.Model):
    name = models.CharField(max_length=100)
    slug = models.SlugField(unique=True)
    description = models.TextField(blank=True)
    
    class Meta:
        verbose_name_plural = "Categories"
        
    def __str__(self):
        return self.name
        
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

class Product(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=200)
    slug = models.SlugField(unique=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="products")
    description = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    stock = models.PositiveIntegerField(default=0)
    available = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    image = models.ImageField(upload_to='products/', blank=True, null=True)
    featured = models.BooleanField(default=False)
    
    class Meta:
        ordering = ['-created_at']
        
    def __str__(self):
        return self.name
        
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)
        
    def get_absolute_url(self):
        return reverse('product_detail', kwargs={'slug': self.slug})
        
    @property
    def is_in_stock(self):
        return self.stock > 0

class Order(models.Model):
    STATUS_CHOICES = (
        ('pending', 'Pending'),
        ('processing', 'Processing'),
        ('shipped', 'Shipped'),
        ('delivered', 'Delivered'),
        ('cancelled', 'Cancelled'),
    )
    
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="orders")
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    shipping_address = models.TextField()
    total_amount = models.DecimalField(max_digits=10, decimal_places=2)
    
    def __str__(self):
        return f"Order {self.id} - {self.user.username}"
        
    @property
    def order_items(self):
        return self.items.all()
        
    @property
    def item_count(self):
        return sum(item.quantity for item in self.order_items)

class OrderItem(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="items")
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField(default=1)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    
    def __str__(self):
        return f"{self.quantity} x {self.product.name}"
        
    @property
    def total_price(self):
        return self.price * self.quantity

# Views example (in views.py)
from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView
from .models import Product, Category

class ProductListView(ListView):
    model = Product
    template_name = 'shop/product_list.html'
    context_object_name = 'products'
    paginate_by = 12
    
    def get_queryset(self):
        queryset = Product.objects.filter(available=True)
        category_slug = self.kwargs.get('category_slug')
        
        if category_slug:
            category = get_object_or_404(Category, slug=category_slug)
            queryset = queryset.filter(category=category)
            
        return queryset
        
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['categories'] = Category.objects.all()
        return context

class ProductDetailView(DetailView):
    model = Product
    template_name = 'shop/product_detail.html'
    context_object_name = 'product'
    slug_url_kwarg = 'slug'

Compartir

Habilidades Python

Python Core
Data Analysis
Web Frameworks
Machine Learning
Testing

¿Interesado en un proyecto similar?

Si estás buscando implementar una solución en Python o tienes un proyecto en mente que requiera habilidades de desarrollo similares, no dudes en contactarme para discutir cómo puedo ayudarte.

Contactar