Quantcast
Channel: Ionic Framework - Ionic Forum
Viewing all 49384 articles
Browse latest View live

Angular 20 and Ionic 8.6 bug or something else

$
0
0

I took the route of setting up a project using the Angular CLI which installed latest Angular 20.0.0 set of packages. I then added the ionic angular package which is 8.6.0. There were problems running ionic serve as the project name could not be recognized so I had to add --project= which overcame that but when I tried to run ionic generate and picked page it compained about path and name and I could not use that tool. Is there a compatibilty issue with these versions?

1 post - 1 participant

Read full topic


Kamal Hinduja Geneva, Switzerland: How do I handle routing and navigation in an Ionic app?

$
0
0

Hi All,

I’m Kamal Hinduja from Geneva, Switzerland. Can anyone share how to handle routing and navigation in an Ionic app?

Please explain in detail.

Thanks in Advance!

Kamal Hinduja Geneva, Switzerland

2 posts - 2 participants

Read full topic

Buiding an .exe with ionic/capacitor with some cordova plugins

$
0
0

Hello everyone,
I’m currently migrating an app from Ionic 4 (Cordova) to Ionic 7 (Capacitor). In order to retain all the original features, I still need to use some Cordova plugins via the @awesome-cordova-plugins package.

In the Cordova version, I was distributing the app on Android, iOS, and Windows. Now, I would like to migrate it to these three platforms using Capacitor as well.

I tried using @capacitor-community/electron for the Windows version, but it crashes whenever a Cordova plugin function is called.

Is there any recommended way to successfully support Windows (desktop) in a Capacitor-based app that still relies on Cordova plugins?

Thank you in advance!

1 post - 1 participant

Read full topic

Source code of new features examples in blog posts announcing Ionic releases

Layanan batalkan pinjaman pinjamyuk

Just Got an Internship Using Ionic & Angular-Best Way to Learn? Looking for Guidance!

$
0
0

Hi everyone,

I just landed an internship at a company that uses Ionic and Angular for their projects, but I’m feeling a bit lost. Most of the tutorials I find are either outdated, not free, or don’t go deep enough into real-world app building. I want to learn these technologies the right way-ideally by building actual apps and understanding professional workflows.

If you’ve been in my shoes or are working with Ionic + Angular in production, could you please share:

  • The best (preferably free) resources or courses for beginners?
  • Any project-based tutorials or YouTube playlists that helped you?
  • Tips for ramping up quickly in a real company environment?
  • What concepts or tools should I focus on first (e.g., Angular basics, Ionic components, RxJS, etc.)?

I’m motivated to learn and contribute, but I’d really appreciate some pointers or a learning path from the community. Any advice, resource links, or even personal stories would mean a lot!

Thanks in advance for your help!

2 posts - 2 participants

Read full topic

//ionic166.rssing.com/chan-53730629/article49287-live.html

$
0
0

Please describe the question in detail and share your code, Hi Ionic team :waving_hand:

I’ve run into an accessibility issue flagged by axe-core on our app that uses Ionic’s ion-radio components. The axe-core report highlights invalid aria-labelledby attribute values on ion-radio and ion-radio-group elements.

Here’s a summary of the violations:


axe-core Report:

  • Element: <ion-radio-group role="radiogroup" aria-labelledby="ion-rg-0-lbl">
    Error: Invalid ARIA attribute value: aria-labelledby="ion-rg-0-lbl"
  • Element: <ion-radio value="full" aria-labelledby="ion-rb-0-lbl" role="radio">
    Error: Invalid ARIA attribute value: aria-labelledby="ion-rb-0-lbl"
  • Element: <ion-radio value="partial" aria-labelledby="ion-rb-1-lbl" role="radio">
    Error: Invalid ARIA attribute value: aria-labelledby="ion-rb-1-lbl"

The issue is that I cannot find these aria-labelledby IDs (ion-rg-0-lbl, ion-rb-0-lbl, ion-rb-1-lbl) in the DOM using the browser’s inspector tools. They’re not present in the HTML, but they’re still being referenced.

This is currently blocking our Axe Core tests from passing and I’m not sure how to work around it.

Thanks,

Vikram

1 post - 1 participant

Read full topic

Redirect back to the app using Universal Links

$
0
0

I am trying to create an IOS app out of the existing angular application which uses keycloak for authentication.

Current behavior :
User opens the app, clicks on the login button which opens capacitor Browser where the user enters the credentials and is automatically redirected back to the app.
Overview of how this works:
I have setup custom URL scheme and have the redirectUri as myapp://… which I listen for in appUrlOpen and close the capacitor Browser and I can see the home screen which the user would see on successful login.
Currently how i handle the redirectUri is having something like

if (data.url.startsWith('myapp://callback/login')) {
        //close the browser when the login is complete to automatically redirect back to the app
        Browser.close();
        ...

I have also setup universal links and can confirm it works as expected.

What I want :
I read in Security | Capacitor Documentation that we should not be having redirects for authentication using custom URL schemes.

How do i make sure that I keep the redirect URI as abc.com and the Browser which usually opens in app would not open the home page in the browser on successful login, and instead would redirect me back to the app once the login is successful and probably when it goes to /homepage.
Are there any limitations with @capacitor/browser which opens the browser as an InAppBrowser apparently?
How do i achieve the expected behavior?

1 post - 1 participant

Read full topic


Google sso implementation in the ios

$
0
0

I am working on an ionic app where have implemented google sso and apple sso. Previously we had issue, after even logout it was not clearing the cookies from the browser and if login again with sso it used previously account. Then we implemented cognito user pool logout url and now it is working in google sso in android but it is not working in ios whereas apple sso is also working fine now.

In ios, the google sso doesn’t show the list of emails logged in the device so we have to enter manually email and password but we do the same in apple sso it should clear the tokens after logout but it’s taking previously email.
we are using amplify

After searching solution i found this question already asked on aws post

and i tried those methods but still it is not working in ios

I would appreciate your replies for this issue.
Thankyou!

1 post - 1 participant

Read full topic

After executing the `ionic capacitor run android - l -- external` in ionic v8, it displays `ERR_CONNECT_TIMED_OUT`?

$
0
0

I guarantee they are on the same WIFI. What should I do? What are the specific steps?
http://192.168.2.174:8100 runs normally in Chrome.

capacitor.config.ts

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'io.ionic.starter',
  appName: 'myApp',
  webDir: 'dist',
  server: {
    androidScheme: "http",
    cleartext: true,
  },
};

export default config;

1 post - 1 participant

Read full topic

Is the ionicframework site down?

Unable to detect scroll in ion-router-outlet

$
0
0

onic Version: Latest (Angular)
Framework: Angular (latest version)
CSS Framework: Tailwind CSS (latest version)
Platform:** Web/Mobile

I’m having trouble getting the scrollbar to appear in my ion-content even though I have plenty of content that should exceed the viewport height. I’ve followed the documentation and added the ion-padding class, but the scrollbar still doesn’t activate.

Current Code Structure
Main Layout (app.component.html or similar):

<ion-header [translucent]="true">
  <ion-toolbar>
    <div class="flex items-center justify-between px-4 py-2">
      <div class="flex items-center space-x-3">
        <div class="w-8 h-8 rounded-full flex items-center justify-center" style="background-color: var(--ion-color-primary);">
          <ion-icon name="home-outline" class="text-lg"></ion-icon>
        </div>
        <h1 class="font-bold text-xl tracking-wide">Mi App</h1>
      </div>

      <div class="flex items-center space-x-3">
        <ion-button fill="clear" size="small">
          <ion-icon name="notifications-outline" slot="icon-only"></ion-icon>
        </ion-button>
        <ion-button fill="clear" size="small">
          <ion-icon name="settings-outline" slot="icon-only"></ion-icon>
        </ion-button>
      </div>
    </div>
  </ion-toolbar>
</ion-header>

<ion-content class="ion-padding">
  <ion-router-outlet></ion-router-outlet>
</ion-content>

<ion-tab-bar>
  <ion-tab-button tab="home" href="/home">
    <ion-icon name="home-outline"></ion-icon>
    <ion-label>Inicio</ion-label>
  </ion-tab-button>

  <ion-tab-button tab="security" href="/security">
    <ion-icon name="shield-outline"></ion-icon>
    <ion-label>Seguridad</ion-label>
  </ion-tab-button>
  
  <ion-tab-button disabled="true">
    <ion-icon name="search-outline"></ion-icon>
    <ion-label>Buscar</ion-label>
  </ion-tab-button>

  <ion-tab-button disabled="true">
    <ion-icon name="heart-outline"></ion-icon>
    <ion-label>Favoritos</ion-label>
  </ion-tab-button>
</ion-tab-bar>

Home Page Content (home.page.html):

<div class="min-h-screen space-y-6 pb-9">
  
  <div class="bg-gradient-to-r from-blue-500 to-purple-600 rounded-lg p-6 text-white">
    <h2 class="text-2xl font-bold mb-2">¡Bienvenido de vuelta!</h2>
    <p class="text-blue-100 mb-4">Explora todas las funcionalidades de tu aplicación</p>
    <ion-button fill="outline" color="light" size="small">
      <ion-icon name="arrow-forward-outline" slot="end"></ion-icon>
      Comenzar
    </ion-button>
  </div>

  <div class="grid grid-cols-2 gap-4">
    <ion-card class="m-0">
      <ion-card-content class="text-center p-4">
        <ion-icon name="trophy-outline" class="text-3xl text-yellow-500 mb-2"></ion-icon>
        <h3 class="font-bold text-lg">125</h3>
        <p class="text-gray-600 text-sm">Logros</p>
      </ion-card-content>
    </ion-card>
    
    <ion-card class="m-0">
      <ion-card-content class="text-center p-4">
        <ion-icon name="people-outline" class="text-3xl text-blue-500 mb-2"></ion-icon>
        <h3 class="font-bold text-lg">1,234</h3>
        <p class="text-gray-600 text-sm">Usuarios</p>
      </ion-card-content>
    </ion-card>
  </div>

  <ion-card>
    <ion-card-header>
      <ion-card-title class="text-lg font-bold">Acciones Rápidas</ion-card-title>
    </ion-card-header>
    <ion-card-content class="p-0">
      <div class="space-y-2">
        <ion-item button>
          <ion-icon name="document-text-outline" slot="start" class="text-blue-500"></ion-icon>
          <ion-label>
            <h3 class="font-semibold">Crear Documento</h3>
            <p class="text-gray-600">Nuevo documento de trabajo</p>
          </ion-label>
          <ion-icon name="chevron-forward-outline" slot="end"></ion-icon>
        </ion-item>
        
        <ion-item button>
          <ion-icon name="camera-outline" slot="start" class="text-green-500"></ion-icon>
          <ion-label>
            <h3 class="font-semibold">Escanear QR</h3>
            <p class="text-gray-600">Escanea código QR</p>
          </ion-label>
          <ion-icon name="chevron-forward-outline" slot="end"></ion-icon>
        </ion-item>
        
        <ion-item button>
          <ion-icon name="share-outline" slot="start" class="text-purple-500"></ion-icon>
          <ion-label>
            <h3 class="font-semibold">Compartir</h3>
            <p class="text-gray-600">Comparte con amigos</p>
          </ion-label>
          <ion-icon name="chevron-forward-outline" slot="end"></ion-icon>
        </ion-item>
      </div>
    </ion-card-content>
  </ion-card>

  <ion-card>
    <ion-card-header>
      <div class="flex justify-between items-center">
        <ion-card-title class="text-lg font-bold">Actividad Reciente</ion-card-title>
        <ion-button fill="clear" size="small">
          Ver todo
        </ion-button>
      </div>
    </ion-card-header>
    <ion-card-content class="p-0">
      <div class="space-y-3 p-4">
        <div class="flex items-center space-x-3">
          <div class="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center">
            <ion-icon name="checkmark-outline" class="text-blue-600"></ion-icon>
          </div>
          <div class="flex-1">
            <p class="font-semibold text-sm">Tarea completada</p>
            <p class="text-gray-600 text-xs">Hace 2 horas</p>
          </div>
        </div>
        
        <div class="flex items-center space-x-3">
          <div class="w-10 h-10 bg-green-100 rounded-full flex items-center justify-center">
            <ion-icon name="add-outline" class="text-green-600"></ion-icon>
          </div>
          <div class="flex-1">
            <p class="font-semibold text-sm">Nuevo proyecto creado</p>
            <p class="text-gray-600 text-xs">Hace 4 horas</p>
          </div>
        </div>
        
        <div class="flex items-center space-x-3">
          <div class="w-10 h-10 bg-orange-100 rounded-full flex items-center justify-center">
            <ion-icon name="mail-outline" class="text-orange-600"></ion-icon>
          </div>
          <div class="flex-1">
            <p class="font-semibold text-sm">Mensaje recibido</p>
            <p class="text-gray-600 text-xs">Hace 6 horas</p>
          </div>
        </div>
      </div>
    </ion-card-content>
  </ion-card>

  <ion-card>
    <ion-card-header>
      <ion-card-title class="text-lg font-bold">Tu Progreso</ion-card-title>
    </ion-card-header>
    <ion-card-content>
      <div class="space-y-4">
        <div>
          <div class="flex justify-between items-center mb-2">
            <span class="text-sm font-medium">Perfil Completado</span>
            <span class="text-sm text-gray-600">75%</span>
          </div>
          <ion-progress-bar value="0.75" color="primary"></ion-progress-bar>
        </div>
        
        <div>
          <div class="flex justify-between items-center mb-2">
            <span class="text-sm font-medium">Objetivos del Mes</span>
            <span class="text-sm text-gray-600">60%</span>
          </div>
          <ion-progress-bar value="0.6" color="success"></ion-progress-bar>
        </div>
        
        <div>
          <div class="flex justify-between items-center mb-2">
            <span class="text-sm font-medium">Tareas Pendientes</span>
            <span class="text-sm text-gray-600">40%</span>
          </div>
          <ion-progress-bar value="0.4" color="warning"></ion-progress-bar>
        </div>
      </div>
    </ion-card-content>
  </ion-card>

  <div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
    <ion-card class="m-0">
      <ion-card-content class="text-center p-4">
        <ion-icon name="analytics-outline" class="text-4xl text-indigo-500 mb-3"></ion-icon>
        <h3 class="font-bold text-lg mb-2">Análisis</h3>
        <p class="text-gray-600 text-sm mb-3">Revisa tus estadísticas y métricas detalladas</p>
        <ion-button fill="outline" size="small">
          Ver más
        </ion-button>
      </ion-card-content>
    </ion-card>
    
    <ion-card class="m-0">
      <ion-card-content class="text-center p-4">
        <ion-icon name="settings-outline" class="text-4xl text-gray-500 mb-3"></ion-icon>
        <h3 class="font-bold text-lg mb-2">Configuración</h3>
        <p class="text-gray-600 text-sm mb-3">Personaliza tu experiencia en la aplicación</p>
        <ion-button fill="outline" size="small">
          Configurar
        </ion-button>
      </ion-card-content>
    </ion-card>
  </div>

  <ion-card>
    <ion-card-header>
      <ion-card-title class="text-lg font-bold">Noticias y Actualizaciones</ion-card-title>
    </ion-card-header>
    <ion-card-content>
      <div class="space-y-4">
        <div class="border-l-4 border-blue-500 pl-4">
          <h4 class="font-semibold text-base mb-1">Nueva función disponible</h4>
          <p class="text-gray-600 text-sm mb-2">Ahora puedes exportar tus datos en formato PDF. Esta nueva característica te permitirá generar reportes profesionales de manera sencilla.</p>
          <span class="text-xs text-blue-600 font-medium">Hace 1 día</span>
        </div>
        
        <div class="border-l-4 border-green-500 pl-4">
          <h4 class="font-semibold text-base mb-1">Mejoras de seguridad</h4>
          <p class="text-gray-600 text-sm mb-2">Hemos implementado autenticación de dos factores para mayor seguridad de tu cuenta. Te recomendamos activarla desde configuración.</p>
          <span class="text-xs text-green-600 font-medium">Hace 3 días</span>
        </div>
        
        <div class="border-l-4 border-orange-500 pl-4">
          <h4 class="font-semibold text-base mb-1">Mantenimiento programado</h4>
          <p class="text-gray-600 text-sm mb-2">El próximo domingo habrá mantenimiento del sistema de 2:00 AM a 4:00 AM. Durante este tiempo el servicio podría estar limitado.</p>
          <span class="text-xs text-orange-600 font-medium">Hace 5 días</span>
        </div>
      </div>
    </ion-card-content>
  </ion-card>

  <ion-card class="bg-gradient-to-r from-purple-500 to-pink-500 text-white">
    <ion-card-content class="text-center p-6">
      <ion-icon name="star-outline" class="text-4xl mb-3"></ion-icon>
      <h3 class="font-bold text-xl mb-2">¿Te gusta la app?</h3>
      <p class="mb-4 text-purple-100">Ayúdanos calificándola en la tienda de aplicaciones</p>
      <ion-button fill="outline" color="light">
        <ion-icon name="star" slot="start"></ion-icon>
        Calificar ahora
      </ion-button>
    </ion-card-content>
  </ion-card>

  <div class="text-center py-4 text-gray-500">
    <p class="text-sm">© 2024 Mi App. Todos los derechos reservados.</p>
    <p class="text-xs mt-1">Versión 1.2.3</p>
  </div>

</div>

Screenshots:

What I’ve Tried

  1. Added ion-padding class to ion-content
  2. Used Tailwind classes like min-h-screen, h-screen, overflow-y-auto
  3. Wrapped content in divs with specific heights
  4. Added substantial content that clearly exceeds viewport height
  5. Tested on different devices and screen sizes

Expected Behavior

The ion-content should show a scrollbar when the content exceeds the available viewport height.

Actual Behavior

No scrollbar appears, and the content seems to be contained within the viewport without the ability to scroll to see all content.

Questions

  1. Is there something specific about using ion-router-outlet inside ion-content that prevents scrolling?
  2. Do I need additional CSS properties when using Tailwind CSS with Ionic?
  3. Are there any known conflicts between Ionic scrolling and Tailwind CSS classes?

1 post - 1 participant

Read full topic

Quran audio application

$
0
0

Please how many MB suppose to use for offline audio application that will work fine without slowing the app.

3 posts - 3 participants

Read full topic

How to test DeepLinks via CLI?

$
0
0

So far the flow for testing deeplinks is rather long and tedious:
Make a change → build the app in release mode, with signed key → upload to phone → uninstall old one, install new one → test

In the android docs they say you can test your deeplinks without this whole rebuilding step:

$ adb shell am start
        -W -a android.intent.action.VIEW
        -d <URI> <PACKAGE>

But when I try to do it (and, mind you, I know that my deeplinks are setup correctly and working), I get the following error:

Starting: Intent { act=android.intent.action.view dat=url... pkg=pkg } Error: Activity not started, unable to resolve Intent { act=android.intent.action.view dat=url... flg=0x10000000 pkg=pgk }

Did anybody make it work?

1 post - 1 participant

Read full topic

Back Button Not Closing Modal in Ionic 7 + Angular 17 + Capacitor 5

$
0
0

I’m using Ionic 7.5.1, Angular 17, and Capacitor 5.

I have a modal opened using ModalController.create(), and I want the Android hardware back button (or gesture) to close the modal, instead of minimizing the app or sending it to the background.

What I tried so far:

  • platform.backButton.subscribeWithPriority(...) → does nothing when modal is open.
  • history.pushState + popstate listener → only works in browser, not on actual Android devices.
  • @HostListener('window:popstate', ['$event']) → same result: works in browser, not on mobile.

Goal:
When a modal is open and the user presses the back button, the modal should close. If no modal is open, the app should navigate one step back.
Right now, when I press the back button with a modal open – the app just minimizes or goes to background instead of closing the modal.

Has anyone solved this for newer versions of Ionic? Would love a working solution that applies to current versions (Ionic 7 / Capacitor 5 / Angular 17).

Thanks in advance!

2 posts - 2 participants

Read full topic


CORS Error while calling the .NET framework API from Ionic app

$
0
0

I’m getting this error while calling the .NET framework APIs, which are running on a Mac machine.

CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I enable the CORS globally and on the controller, both work when the endpoints are hit on the local system, but when trying to hit from a remote Mac machine get the above error. I tried a different approach.

Could anyone please tell me the exact procedure to achieve this?

2 posts - 2 participants

Read full topic

Capacitor Geofence plugin

$
0
0

I need to implement Geofencing feature in a Ionic 8 / Capacitor 6 app. I found an old ionic-native/geofence plugin . Is there an equivalent plugin in capacitor community or elsewhere?

1 post - 1 participant

Read full topic

It's crossing out my line but it's not commented or anything like that, what can I do?

$
0
0

I already deleted it, closed it and opened it again, I redid the line, played in the gpt chat and I can’t.

2 posts - 2 participants

Read full topic

Opening another app(files app) in a modal in ionic

$
0
0

i need a way to open an app(files app) in a modal in ionic similar to how WhatsApp does it, it makes the app more accessible to users with low end androids.

7 posts - 2 participants

Read full topic

[Help] Prevent ion-content from scrolling on input focus in Ionic

$
0
0

Hello everyone! :waving_hand:

I’ve created a shared layout template for my Ionic pages. Most of my pages have very little content, so my goal is to avoid any scrolling behavior altogether.

To achieve this, the simplest solution I found was to set scrollY="false" on <ion-content>. It works to prevent scrolling in general, but when scrollY is set to false and an <input> gets focused, the page scrolls automatically — which breaks the layout by pushing content out of view (especially on mobile).

Is there a better or more recommended way to prevent this automatic scroll on input focus, ideally without having to disable scroll completely?

Any tips or best practices would be greatly appreciated. Thanks in advance!

My example:

layout.component.html

<ion-header class="ion-no-border">
  <ion-toolbar [color]="toolbarColor">
    @if (backbuttonHref) {
      <ion-buttons slot="start">
        <ion-back-button [defaultHref]="backbuttonHref"></ion-back-button>
      </ion-buttons>
    }
    <ion-title>{{ title }}</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content [fullscreen]="true" class="ion-padding" [scrollY]="scrollY">
  <ion-grid fixed>
    <ion-row class="ion-justify-content-center">
      <ion-col size="12" size-md="8" size-lg="6" size-xl="4">
        <div class="ion-text-center ion-margin-bottom">
          <ion-icon
            [name]="iconName"
            [color]="iconColor"
            [style.font-size]="iconSize">
          </ion-icon>
          <h2>{{ heading }}</h2>
          @if (description) {
            <ion-text color="medium">
              <p>{{ description }}</p>
            </ion-text>
          }
        </div>

        <ng-content></ng-content>

      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

layout.component.ts

import {Component, OnInit, Input} from '@angular/core';
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {
  IonBackButton, IonButtons,
  IonCol,
  IonContent,
  IonGrid,
  IonHeader,
  IonIcon, IonRow, IonText, IonTitle, IonToolbar
} from "@ionic/angular/standalone";
import {addIcons} from "ionicons";
import {
  mailOutline,
  lockClosedOutline,
  personOutline,
  personAddOutline,
  homeOutline,
  settingsOutline,
  notificationsOutline,
  heartOutline,
  starOutline,
  checkmarkCircleOutline,
  alertCircleOutline,
  informationCircleOutline,
  warningOutline,
  shieldCheckmarkOutline
} from "ionicons/icons";

@Component({
  selector: 'app-layout',
  templateUrl: './layout.component.html',
  styleUrls: ['./layout.component.scss'],
  imports: [
    FormsModule,
    IonCol,
    IonContent,
    IonGrid,
    IonHeader,
    IonIcon,
    IonRow,
    IonText,
    IonTitle,
    IonToolbar,
    ReactiveFormsModule,
    IonBackButton,
    IonButtons
  ]
})
export class LayoutComponent {
  @Input() title: string = '';
  @Input() iconName: string = '';
  @Input() heading: string = '';
  @Input() description?: string;
  @Input() toolbarColor: string = 'primary';
  @Input() iconColor: string = 'primary';
  @Input() iconSize: string = '64px';
  @Input() scrollY = false;
  @Input() backbuttonHref?: string;

  constructor() {
    addIcons({
      mailOutline,
      lockClosedOutline,
      personOutline,
      personAddOutline,
      homeOutline,
      settingsOutline,
      notificationsOutline,
      heartOutline,
      starOutline,
      checkmarkCircleOutline,
      alertCircleOutline,
      informationCircleOutline,
      warningOutline,
      shieldCheckmarkOutline
    });
  }
}

forgot-password.page.html

<app-layout
  title="Recuperar Senha"
  heading="Esqueceu sua senha?"
  description="Não se preocupe! Insira seu e-mail abaixo e nós enviaremos um link para você criar uma nova senha."
  iconName="mail-outline"
  backbuttonHref="/login"
>
  <form [formGroup]="forgotPasswordForm" (ngSubmit)="onForgotPasswordSubmit()">
    <ion-list lines="full" class="ion-no-margin ion-no-padding">
      <ion-item>
        <ion-input
          label="E-mail"
          labelPlacement="floating"
          formControlName="email"
          type="email"
          placeholder="seuemail@exemplo.com"
          required
          errorText="Por favor, insira um e-mail válido.">
        </ion-input>
      </ion-item>

    </ion-list>
    
    <ion-button
      expand="block"
      type="submit"
      class="ion-margin-top"
      [disabled]="isSubmitting">
      <ion-spinner *ngIf="isSubmitting" name="crescent"></ion-spinner>
      <span *ngIf="!isSubmitting">Enviar Link de Recuperação</span>
    </ion-button>
  </form>
</app-layout>

forgot-password.component.ts

import {Component, OnInit, inject} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators} from '@angular/forms';
import {Router} from '@angular/router';
import {
  IonList,
  IonItem,
  IonInput,
  IonButton,
  IonSpinner
} from '@ionic/angular/standalone';
import {mailOutline} from 'ionicons/icons';
import {addIcons} from 'ionicons';
import {UiService} from "../../../core/services/ui.service";
import {AuthService} from "../../../core/services/auth.service";
import {LayoutComponent} from "../../../shared/layout/layout.component";

@Component({
  selector: 'app-forgot-password',
  templateUrl: './forgot-password.page.html',
  styleUrls: ['./forgot-password.page.scss'],
  standalone: true,
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    IonList,
    IonItem,
    IonInput,
    IonButton,
    IonSpinner,
    LayoutComponent
  ],
  providers: [AuthService, UiService]
})
export class ForgotPasswordPage implements OnInit {

  forgotPasswordForm!: FormGroup;
  isSubmitting = false;

  private fb = inject(FormBuilder);
  private router = inject(Router);
  private authService = inject(AuthService);
  private uiService = inject(UiService);

  constructor() {
    addIcons({mailOutline});
  }

  ngOnInit() {
    this.initializeForm();
  }

  private initializeForm(): void {
    this.forgotPasswordForm = this.fb.group({
      email: ['', [Validators.required, Validators.email]],
    });
  }

  get email() {
    return this.forgotPasswordForm.get('email');
  }

  async onForgotPasswordSubmit(): Promise<void> {
    if (this.forgotPasswordForm.invalid) {
      this.forgotPasswordForm.markAllAsTouched();
      return;
    }

    this.isSubmitting = true;

    await this.uiService.presentLoading('Enviando código para redefinição de senha...');

    this.authService.forgotPassword(this.forgotPasswordForm.value).subscribe({
        next: () => {
          this.isSubmitting = false;
          this.uiService.dismissLoading();
          this.router.navigate(['/reset-password', this.email?.value], {replaceUrl: true});
        },
        error: err => {
          this.isSubmitting = false;
          this.uiService.dismissLoading();
          this.uiService.presentToast(
            err.message || 'Falha ao enviar código de redefinição. Verifique se o e-mail está correto.',
            'danger'
          );
        }
      }
    )
  }
}

Screenshots


1 post - 1 participant

Read full topic

Viewing all 49384 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>