// Form that functions as both a way to edit or add users to the database
// Author: Cameron Hayes

unit View.User.Add;

interface

uses
  System.SysUtils, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
  WEBLib.Forms, WEBLib.Dialogs, Vcl.Controls, Vcl.StdCtrls, WEBLib.StdCtrls,
  WEBLib.DBCtrls, XData.Web.Client, WEBLib.ExtCtrls, Vcl.Menus, WEBLib.Menus;

type
  TFViewEditUser = class(TWebForm)
    WebLabel2: TWebLabel;
    WebLabel3: TWebLabel;
    WebLabel5: TWebLabel;
    WebLabel7: TWebLabel;
    edtEmail: TWebEdit;
    edtPassword: TWebEdit;
    btnConfirm: TWebButton;
    edtFullname: TWebEdit;
    edtUsername: TWebEdit;
    XDataWebClient1: TXDataWebClient;
    btnCancel: TWebButton;
    WebTimer1: TWebTimer;
    lblactive: TWebLabel;
    cbStatus: TWebCheckBox;
    lblRights: TWebLabel;
    edtRights: TWebEdit;
    lblAccess: TWebLabel;
    cbAccess: TWebComboBox;
    lblQB: TWebLabel;
    edtQB: TWebEdit;
    procedure WebFormCreate(Sender: TObject);
    procedure btnConfirmClick(Sender: TObject);
    procedure btnCancelClick(Sender: TObject);
    procedure WebTimer1Timer(Sender: TObject);
  private
    { Private declarations }
    FMessage: string;
    Mode: string;
    Username: string;
    Password: string;
    FullName: string;
    Status: string;
    Email: string;
    Access: string;
    Rights: string;
    QB: string;
    [async] procedure EditUser();
    [async] function AddUser(): string;
  public
    { Public declarations }
    Info: string;
    class function CreateForm(AElementID, Mode, Username, Password, Name, Status, Email,
                               Access, Rights, QB: string): TWebForm;
  end;

var
  FViewEditUser: TFViewEditUser;

implementation

uses
Windows,
View.Main,
View.Users,
VCL.Dialogs,
ConnectionModule,
Utils;

procedure TFViewEditUser.btnCancelClick(Sender: TObject);
// Cancels the edit or addition
begin
  Info := 'Failure: Changes discarded!';
  FViewMain.ShowUserForm(Info);
end;


function TFViewEditUser.AddUser: string;
// Sends UserInfo over to the server so it can be added to the database
var
  userInfo: string;
  xdcResponse: TXDataClientResponse;
  responseString: TJSObject;
begin
  userInfo := '&username=' + edtUsername.Text +
              '&fullname=' + edtFullName.Text +
              '&password=' + edtPassword.Text +
              '&status=' + BoolToStr(cbStatus.Checked) +
              '&email=' + edtEmail.Text +
              '&access=' + cbAccess.Text +
              '&newuser=' + edtUsername.Text +
              '&rights=' + edtRights.Text +
              '&QB=' + edtQB.Text;

  try
    xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddUser', [userInfo]));
    responseString := TJSObject(xdcResponse.Result);
    Info := string(responseString['value']);
    if Info.ToLower.Contains('failure') then
      ShowToast(Info)
    else
      FViewMain.ShowUserForm(Info);
  except
    on E: EXDataClientRequestException do
      Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
  end;
end;


procedure TFViewEditUser.EditUser();
// Sends EditOptions over to the server so the given user can be editted
var
  editOptions: string;
  xdcResponse: TXDataClientResponse;
  responseString: TJSObject;
begin

  editOptions := 'username=' + Username +
                  '&fullname=' + edtFullName.Text +
                  '&password=' + edtPassword.Text +
                  '&status=' + BoolToStr(cbStatus.Checked) +
                  '&email=' + edtEmail.Text +
                  '&access=' + cbAccess.Text +
                  '&newuser=' + edtUsername.Text +
                  '&rights=' + edtRights.Text +
                  '&QB=' + edtQB.Text;
  try
    xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.EditUser',
          [editOptions]));
    responseString :=  TJSObject(xdcResponse.Result);
    Info := string(responseString['value']);
    if Info.ToLower.Contains('failure') then
      ShowToast(Info)
    else
      FViewMain.ShowUserForm(Info);
  except
    on E: EXDataClientRequestException do
      Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
  end;
end;

class function TFViewEditUser.CreateForm(AElementID, Mode, Username, Password, Name, Status, Email,
                               Access, Rights, QB: string): TWebForm;
// Autofills known information about a user on create
  procedure AfterCreate(AForm: TObject);
  begin
    TFViewEditUser(AForm).Mode := Mode;
    TFViewEditUser(AForm).Username := Username;
    TFViewEditUser(AForm).FullName := Name;
    TFViewEditUser(AForm).Status := Status;
    TFViewEditUser(AForm).Email := Email;
    TFViewEditUser(AForm).Access := Access;
    TFViewEditUser(AForm).Rights := Rights;
    TFViewEditUser(AForm).QB := QB;
  end;

{$R *.dfm}
begin
  Application.CreateForm(TFViewEditUser, AElementID, Result, @AfterCreate);
end;



procedure TFViewEditUser.WebFormCreate(Sender: TObject);
// Autofills known information about a user on create
begin
  if FMessage <> '' then
    ShowToast(FMessage);
  edtUsername.Text := Username;
  edtFullName.Text := FullName;
  if Mode = 'EDIT' then
  begin
    edtPassword.Text := 'hidden';
  end;
  edtEmail.Text := Email;
  cbAccess.Text := Access;
  edtRights.Text := Rights;
  edtQB.Text :=  QB;
  if Status = 'ACTIVE' then
    cbStatus.checked := true;
end;

procedure TFViewEditUser.WebTimer1Timer(Sender: TObject);
begin
  WebTimer1.Enabled := False;
  Utils.HideSpinner('spinner');
  if (not Info.Contains('Failure')) then
  begin
    FViewMain.ShowUserForm(Info);
  end
  else
    showToast(Info);
end;


procedure TFViewEditUser.btnConfirmClick(Sender: TObject);
var
  FormEl: TJSHTMLFormElement;
  AllValid: Boolean;
begin
  FormEl := TJSHTMLFormElement(document.getElementById('userprofileform'));

  // Clear previous invalid state
  edtUsername.ElementHandle.classList.remove('is-invalid');
  edtFullName.ElementHandle.classList.remove('is-invalid');
  edtEmail.ElementHandle.classList.remove('is-invalid');
  if Assigned(FormEl) then
    FormEl.classList.remove('was-validated');

  AllValid := True;

  if edtUsername.Text.Trim = '' then
  begin
    edtUsername.ElementHandle.classList.add('is-invalid');
    AllValid := False;
  end;

  if edtFullName.Text.Trim = '' then
  begin
    edtFullName.ElementHandle.classList.add('is-invalid');
    AllValid := False;
  end;

  if not TJSHTMLInputElement(edtEmail.ElementHandle).checkValidity then
  begin
    edtEmail.ElementHandle.classList.add('is-invalid');
    AllValid := False;
  end;

  if not AllValid then
    Exit;

  ShowConfirmationModal(
    'Are you sure you want to save changes?',
    'Yes',
    'No',
    procedure(confirmed: Boolean)
    begin
      if confirmed then
        if mode = 'ADD' then
          AddUser()
        else
          EditUser();
    end
  );
end;


end.
