Skip to main content

SignIn.EmailForm

Complete email/password authentication interface combining all form elements with validation, error handling, and customization options. Provides compound components for building flexible sign-in forms with built-in authentication logic.

Prerequisites

Before using the Sign-In module, you must configure your ovokClient with a valid tenant code.

Obtaining Your Tenant Code

To get your organization's tenant code, use the Ovok API to receive organization codes via email:

curl -X POST https://api.ovok.com/organizations/code/email \
-H "Content-Type: application/json" \
-d '{"email": "your-email@example.com"}'

For detailed API documentation, refer to the Ovok API Reference.

Configuring Your Client

Once you receive your tenant code, update your ovokClient configuration in app/_layout.tsx:

const ovokClient = new OvokClient({
...
tenantCode: "your-tenant-code-here", // Replace with your actual tenant code
});

Quick Start Example

import { AuthResponse } from "@ovok/core";
import { SignIn, useAppTheme } from "@ovok/native";
import React from "react";
import { StyleSheet } from "react-native";

// Static styles outside component
const styles = StyleSheet.create({
form: {
flex: 1,
},
});

const LoginScreen = () => {
const theme = useAppTheme();

const handleSuccess = (response: AuthResponse) => {
console.log("Login successful:", response);
// Handle successful authentication
};

const handleError = (error: Error) => {
console.error("Login failed:", error);
// Handle authentication error
};

return (
<SignIn.EmailForm
loginType="Patient"
tenantCode="your-tenant-code"
onSuccess={handleSuccess}
onError={handleError}
style={[
styles.form,
{
padding: theme.spacing(12),
gap: theme.spacing(12),
},
]}
>
<SignIn.EmailForm.Inputs />
<SignIn.EmailForm.ForgotPassword />
<SignIn.EmailForm.Spacing percentage={3} />
<SignIn.EmailForm.SigninButton />
</SignIn.EmailForm>
);
};

export default LoginScreen;

Props

PropTypeRequiredDefaultDescription
loginType"Patient" | "Practitioner"-User type for authentication
tenantCodestring✓*-Organization tenant code (required for Patient login)
onSuccess(response: AuthResponse) => void-undefinedCallback for successful authentication
onError(error: Error) => void-undefinedCallback for authentication errors
onSubmit(values, formikHelpers) => Promise<void>-undefinedCustom submit handler (overrides default auth logic)
customValidations{ [key]: Yup.StringSchema | Function }-undefinedCustom validation rules for form fields
styleStyleProp<ViewStyle>-undefinedContainer style overrides
testIDstring-undefinedTest identifier for automation
childrenReactNode-undefinedChild components (Inputs, Button, etc.)

Note: tenantCode is required when loginType is "Patient" and optional when loginType is "Practitioner".

Note: Either use onSuccess/onError for default authentication or onSubmit for custom handling. Both approaches cannot be used together.

Child Components

Localization

The SignIn.EmailForm component uses these translation keys that should be defined in your localization files:

{
"sign-in": {
"email": "Email",
"password": "Password",
"button": "Sign In",
"forgot-password": "Forgot password?",
"form": {
"email": {
"invalid": "Invalid email address",
"required": "Email is required"
},
"password": {
"required": "Password is required"
}
}
}
}

Translation Key Usage

  • sign-in.email - Email input field label
  • sign-in.password - Password input field label
  • sign-in.button - Submit button text
  • sign-in.forgot-password - Forgot password link text
  • sign-in.form.email.invalid - Email validation error message
  • sign-in.form.email.required - Required email field error
  • sign-in.form.password.required - Required password field error

Common Patterns

With Custom Validation

import { SignIn, useAppTheme } from "@ovok/native";
import React from "react";
import { StyleSheet } from "react-native";
import * as Yup from "yup";

// Static styles outside component
const styles = StyleSheet.create({
form: {
flex: 1,
},
});

const customValidations = {
email: (existingRule: Yup.StringSchema) =>
existingRule
.email("Invalid email address")
.matches(/@ovok\.com$/, "Email must be from ovok.com domain"),
};

export const CustomValidationLoginForm = () => {
const theme = useAppTheme();

return (
<SignIn.EmailForm
loginType="Practitioner"
customValidations={customValidations}
style={[
styles.form,
{
gap: theme.spacing(4),
},
]}
>
<SignIn.EmailForm.Inputs />
<SignIn.EmailForm.SigninButton />
</SignIn.EmailForm>
);
};