Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Current »

  1. Login API

import {
  Body, Controller, Post, UsePipes, ValidationPipe
} from '@nestjs/common';
import { DataResponse } from 'src/core';
import { LoginPasswordPayload } from 'src/payloads';
import { AuthService } from 'src/services';

@Controller('/auth/login')
export class LoginController {
  constructor(
    private authService: AuthService
  ) {}

  @Post()
  @UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
  async register(
    @Body() payload: LoginPasswordPayload
  ) {
    const res = await this.authService.loginWithPassword(payload);
    return DataResponse.ok(res);
  }
}
  1. Login form

'use client';

import Link from 'next/link';
import { Formik, Form, Field, FieldProps } from 'formik';
import { signIn } from 'next-auth/react';
import { useTranslation } from 'react-i18next';
import * as yup from 'yup';
import { FormItem, Input } from '@components/ui/form';
import { useState } from 'react';
import { FormattedMessage } from '@components/i18n';
import { useMainThemeLayout } from 'src/providers/main-layout.provider';

const schema = yup.object().shape({
  username: yup.string().required('Username is required!'),
  password: yup.string().required('Password is required!')
});

export default function Login() {
  const { t } = useTranslation();
  const [error, setError] = useState<string | null>();
  const { register, forgotPassword, closePopup } = useMainThemeLayout();


  return (
    <div className="w-full space-y-5 p-10 text-center">
      <Link href="/" className="font-bold text-4xl text-center">
        xStreamer
      </Link>
      <h2 className="text-center text-2xl font-bold leading-9 tracking-tigh">
        {t('signin', 'Sign in')}
      </h2>
      <Formik
        initialValues={{ username: '', password: '' }}
        validationSchema={schema}
        onSubmit={async (values, actions) => {
          const res = await signIn('credentials', {
            ...values,
            redirect: false
          });

          if (res && res.ok) {
            closePopup();
            // loadProfile();
            return;
          }

          setError(res!.error);
          actions.setSubmitting(false);
        }}
      >
        {({ handleSubmit }) => (
          <Form className="space-y-3" onSubmit={handleSubmit}>
            <Field name="username">
              {({ field, meta }: FieldProps) => (
                <FormItem>
                  <Input placeholder="Username" {...field} />
                  {meta.touched && !!meta.error && (
                    <FormItem.Error>{meta.error}</FormItem.Error>
                  )}
                </FormItem>
              )}
            </Field>

            <div>
              <Field name="password">
                {({ field, meta }: FieldProps) => (
                  <FormItem>
                    <Input type="password" placeholder="Password" {...field} />
                    {meta.touched && !!meta.error && (
                      <FormItem.Error>{meta.error}</FormItem.Error>
                    )}
                  </FormItem>
                )}
              </Field>
            </div>
            <div className="flex items-center justify-between">
              <div className="text-sm text-primary">
                <button onClick={forgotPassword} role="button" type="button">
                  <FormattedMessage
                    id="forgotPassword"
                    defaultValue="Forgot password"
                    subifx="?"
                  />
                </button>
              </div>
            </div>
            {error && (
              <div
                className="bg-red-100 dark:bg-red-950  border border-red-900 text-red-700 dark:text-white px-4 py-3 rounded relative"
                role="alert"
              >
                <span className="text-sm font-medium">{error}</span>
              </div>
            )}

            <div className="text-center">
              <button
                type="submit"
                className="rounded-md bg-orange-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-orange-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-orange-600"
              >
                {t('signin', 'Sign in')}
              </button>
            </div>
          </Form>
        )}
      </Formik>

      <p className="mt-10 text-center text-sm text-gray-500">
        Don&apos;t have an account?
        {' '}
        <a
          onClick={register}
          className="font-semibold leading-6 cursor-pointer hover:text-primary"
        >
          {t('signup', 'Sign Up')}
        </a>
      </p>
    </div>
  );
}
  • No labels