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

Versión móvil optimizada del sitio

Sección de servicios con navegación mejorada
Ejemplo de Código
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'
Habilidades Python
¿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