Skip to main content

Overview

My Tickets is your personal dashboard for managing tickets you’ve created, updating your profile information, and configuring security settings. It provides a centralized view of all tickets associated with your account.
This page shows all tickets where you are the creator (created_by matches your user ID), regardless of acceptance status or current assignee.

Page Tabs

The My Tickets page is organized into three tabs:

Mis tickets

View and filter all tickets you’ve created.

Datos personales

Update your name, view email and location info.

Seguridad

Change your password with current password verification.

My Tickets Tab

Ticket List

Displays all tickets you’ve created with the following information: Card View (Mobile):
  • Ticket ID and title
  • Description preview
  • Priority and status badges
  • First attached image thumbnail
  • Location name
  • Requester name
  • Incident date
Table View (Desktop):
  • ID column with ticket number
  • Title and description (truncated)
  • Priority badge (color-coded)
  • Status badge (color-coded)
  • Location name
  • Incident date
  • Created date
  • Image thumbnail

Filtering

Filter your tickets using multiple criteria:

Search

Search by ticket ID, title, description, or requester name (minimum 2 characters).

Status

Filter by ticket status: Pendiente, En Ejecución, Finalizadas.

Priority

Filter by priority level: Baja, Media, Alta.

Date Range

Filter by creation date range with from/to pickers.
Filter Implementation:
const filteredTickets = tickets.filter((ticket) => {
  // Search filter (minimum 2 chars)
  if (term.length >= 2) {
    const haystack = [
      String(ticket.id),
      ticket.title,
      ticket.description,
      ticket.requester,
    ].join(' ').toLowerCase();
    if (!haystack.includes(term)) return false;
  }
  
  // Status filter
  if (statuses.length > 0 && !statuses.includes(ticket.status)) {
    return false;
  }
  
  // Priority filter
  if (priorities.length > 0 && !priorities.includes(ticket.priority)) {
    return false;
  }
  
  // Date range filter
  if (createdRange?.from || createdRange?.to) {
    const createdDate = ticket.created_at.slice(0, 10);
    if (createdRange.from && createdDate < createdRange.from) return false;
    if (createdRange.to && createdDate > createdRange.to) return false;
  }
  
  return true;
});
See ~/workspace/source/src/pages/MyTicketsPage.tsx:217 for full implementation.

Pagination

  • Page size: 8 tickets per page
  • Client-side pagination (all tickets loaded)
  • Previous/Next controls
  • Page indicator: “Página X de Y - Z total”

Real-time Updates

Tickets refresh automatically when:
  • New tickets are created by you
  • Existing tickets are updated
  • Data invalidation events fire
import { onDataInvalidated } from '@/lib/dataInvalidation';

useEffect(() => {
  return onDataInvalidated('tickets', () => {
    if (!userId) return;
    loadTickets();
  });
}, [userId]);
See ~/workspace/source/src/pages/MyTicketsPage.tsx:205.

Personal Data Tab

Manage your profile information:

Editable Fields

Name:
  • Text input for first name
  • Required field
  • Maximum 60 characters
Last Name:
  • Text input for last name
  • Required field
  • Maximum 60 characters

Read-Only Fields

Email:
  • Display only
  • Cannot be changed from this screen
  • Managed by administrators
Location:
  • Display only
  • Shows facility location name
  • Assigned by administrators
Roles:
  • Display only
  • Comma-separated list of assigned roles
  • Managed by administrators
To change email, location, or roles, contact your administrator. These fields require admin-level access to modify.

Save Changes

1

Edit name fields

Update your first name and/or last name in the input fields.
2

Verify changes

Ensure both fields have valid values (non-empty, trimmed).
3

Click Save

Click the “Guardar cambios” button. It’s disabled until you make changes.
4

Confirmation

Success toast appears, and profile refreshes with updated values.
Validation:
  • Both name and last name required
  • Must be different from current values
  • Whitespace trimmed automatically
Implementation:
const handleSaveProfile = async (event: React.FormEvent) => {
  event.preventDefault();
  
  const normalizedName = name.trim();
  const normalizedLastName = lastName.trim();
  
  if (!normalizedName || !normalizedLastName) {
    showToastError('Completa nombre y apellido para guardar.');
    return;
  }
  
  const result = await update({
    name: normalizedName,
    last_name: normalizedLastName,
  });
  
  if (!result.ok) {
    showToastError(result.error ?? 'No se pudo actualizar tu perfil.');
    return;
  }
  
  await refresh({ silent: true });
  showToastSuccess('Datos personales actualizados.');
};
See ~/workspace/source/src/pages/MyTicketsPage.tsx:290.

Security Tab

Change your account password securely:

Password Change Form

Required Fields:
1

Current Password

Enter your current password for verification. This is required to prevent unauthorized changes.
2

New Password

Enter your desired new password. Must be at least 8 characters.
3

Confirm Password

Re-enter the new password to confirm. Must match exactly.

Password Requirements

Minimum Length

At least 8 characters required

Cannot Match Current

New password must differ from current password

Confirmation Match

Confirmation must exactly match new password

Recommendations

Combine letters, numbers, and symbols for strength

Change Process

1

Enter current password

Type your current password in the first field.
2

Enter new password

Type your desired new password (8+ characters).
3

Confirm new password

Re-type the new password in the confirmation field.
4

Submit form

Click “Actualizar contraseña” button.
5

Verification

System verifies current password and updates if valid.
6

Success

Form clears and success toast appears. Use new password on next login.

Security Validation

Client-side checks:
if (!currentPassword.trim()) {
  showToastError('Debes indicar la contraseña actual.');
  return;
}

if (newPassword.length < 8) {
  showToastError('La nueva contraseña debe tener al menos 8 caracteres.');
  return;
}

if (newPassword === currentPassword) {
  showToastError('La nueva contraseña debe ser diferente a la actual.');
  return;
}

if (newPassword !== confirmPassword) {
  showToastError('La confirmación no coincide con la nueva contraseña.');
  return;
}
Server-side verification:
  • Current password validated against auth system
  • New password hashed before storage
  • Session remains valid after change
See ~/workspace/source/src/pages/MyTicketsPage.tsx:328.

Service Integration

Loading Tickets

import { getTicketsByUserId } from '@/services/ticketService';

const tickets = await getTicketsByUserId(userId);
Filters by created_by field and excludes archived tickets. See ~/workspace/source/src/services/ticketService.ts:197.

Updating Profile

import { useUser } from '@/context/UserContext';

const { update, refresh } = useUser();

const result = await update({
  name: 'John',
  last_name: 'Doe',
});

if (result.ok) {
  await refresh({ silent: true });
}
Uses UserContext for profile management. See context implementation.

Changing Password

import { changeCurrentUserPassword } from '@/services/userService';

await changeCurrentUserPassword(
  currentPassword,
  newPassword
);
See ~/workspace/source/src/services/userService.ts for password change implementation.

Data Model

Ticket Display

interface TicketRow {
  id: number;
  title: string;
  description: string;
  priority: 'Baja' | 'Media' | 'Alta';
  status: 'Pendiente' | 'En Ejecución' | 'Finalizadas';
  location_id: number;
  location_name?: string;
  requester: string;
  incident_date: string;
  image?: string;
  created_at: string;
}

Profile Data

interface UserProfile {
  id: string;
  name: string;
  last_name: string;
  email: string;
  location_id: number | null;
  is_active: boolean;
}

UI Components

MyTicketsPage

Main page component at ~/workspace/source/src/pages/MyTicketsPage.tsx:82 State Management:
  • Active tab selection
  • Ticket loading and filtering
  • Profile form state
  • Password form state
  • Pagination state

TabButton

Reusable tab button component at ~/workspace/source/src/pages/MyTicketsPage.tsx:55 Props:
  • active: boolean - Highlight state
  • label: string - Tab text
  • icon: LucideIcon - Tab icon
  • onClick: () => void - Click handler

MyTicketsFiltersBar

Filter bar component at ~/workspace/source/src/components/dashboard/ticket/MyTicketsFiltersBar.tsx Features:
  • Search input with debouncing
  • Status multi-select
  • Priority multi-select
  • Date range picker
  • Tab buttons integration

Styling

Priority Badges

function priorityChipClass(priority: 'Baja' | 'Media' | 'Alta') {
  if (priority === 'Alta') return 'bg-orange-50 text-orange-700 border-orange-200';
  if (priority === 'Media') return 'bg-amber-50 text-amber-700 border-amber-200';
  return 'bg-emerald-50 text-emerald-700 border-emerald-200';
}
See ~/workspace/source/src/pages/MyTicketsPage.tsx:42.

Status Badges

function statusChipClass(status: 'Pendiente' | 'En Ejecución' | 'Finalizadas') {
  if (status === 'En Ejecución') return 'bg-sky-50 text-sky-700 border-sky-200';
  if (status === 'Finalizadas') return 'bg-emerald-50 text-emerald-700 border-emerald-200';
  return 'bg-amber-50 text-amber-700 border-amber-200';
}
See ~/workspace/source/src/pages/MyTicketsPage.tsx:48.

Responsive Design

Mobile Layout (<768px)

  • Tab buttons in responsive flex grid
  • Card-based ticket display
  • Stacked form fields
  • Full-width buttons

Desktop Layout (≥768px)

  • Horizontal tab buttons
  • Table-based ticket display
  • Two-column form grids
  • Aligned form buttons

Accessibility

Keyboard Navigation

  • Tab through all interactive elements
  • Enter to activate buttons
  • Form submission with Enter key
  • Escape to clear focus

Screen Reader Support

  • Form labels associated with inputs
  • Button states announced
  • Error messages read aloud
  • Status changes announced

ARIA Attributes

<input
  id="profile-name"
  aria-label="First name"
  aria-required="true"
  aria-invalid="false"
/>

<button
  type="submit"
  aria-disabled="true"
  aria-label="Save profile changes"
>

Best Practices

For Users

  1. Review Tickets Regularly - Check your created tickets for updates
  2. Keep Profile Updated - Ensure name is current
  3. Use Strong Passwords - Combine letters, numbers, symbols
  4. Change Password Periodically - Update every 90 days
  5. Clear Filters - Reset filters to see all tickets

For Security

  1. Don’t Share Passwords - Keep credentials private
  2. Use Unique Passwords - Don’t reuse across systems
  3. Enable MFA - If available (future feature)
  4. Verify Current Password - Required for changes
  5. Log Out When Done - On shared devices

Troubleshooting

Tickets not appearing

  • Check filter settings
  • Verify tickets were created by your account
  • Confirm tickets are not archived
  • Refresh the page

Cannot save profile

  • Ensure both name fields filled
  • Verify changes made
  • Check network connection
  • Review browser console

Password change fails

  • Verify current password correct
  • Check new password meets requirements
  • Ensure confirmation matches
  • Wait and retry if server busy

Filters not working

  • Clear all filters and reapply
  • Check filter values valid
  • Ensure minimum search length (2 chars)
  • Verify date range logical