Add Pennyzo API status checker scripts, report viewer, and documentation
This commit is contained in:
102
src/examples/pennyzo-api-usage-examples.ts
Normal file
102
src/examples/pennyzo-api-usage-examples.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { pennyzoApi } from '../services';
|
||||
|
||||
/**
|
||||
* This file contains examples of how to use the PennyzoApiService
|
||||
* These are meant to be reference examples and not actual code to run.
|
||||
*/
|
||||
|
||||
// Example 1: System health check (public endpoint)
|
||||
async function checkSystemHealth() {
|
||||
try {
|
||||
const health = await pennyzoApi.checkHealth();
|
||||
console.log('System status:', health.status);
|
||||
console.log('Service:', health.service);
|
||||
console.log('Version:', health.version);
|
||||
return health;
|
||||
} catch (error) {
|
||||
console.error('Error checking health:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Example 2: User registration (public endpoint)
|
||||
async function registerNewUser(userData: any) {
|
||||
try {
|
||||
const registeredUser = await pennyzoApi.registerUser({
|
||||
first_name: userData.firstName,
|
||||
last_name: userData.lastName,
|
||||
email: userData.email,
|
||||
company_name: userData.companyName,
|
||||
company_type: userData.companyType,
|
||||
gst_registered: userData.isGstRegistered,
|
||||
gst_number: userData.gstNumber,
|
||||
industry: userData.industry,
|
||||
// Other optional fields
|
||||
});
|
||||
|
||||
console.log('User registered successfully:', registeredUser);
|
||||
return registeredUser;
|
||||
} catch (error) {
|
||||
console.error('Registration failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Example 3: Login and authentication flow
|
||||
async function loginUser(email: string, password: string) {
|
||||
try {
|
||||
const loginResult = await pennyzoApi.login(email, password);
|
||||
console.log('Login successful, token type:', loginResult.token_type);
|
||||
console.log('Token expiration:', loginResult.expires_in);
|
||||
|
||||
// Token is automatically stored and will be used in subsequent API calls
|
||||
|
||||
// Get the current user's details (authenticated call)
|
||||
const currentUser = await pennyzoApi.getCurrentUser();
|
||||
console.log('Current user:', currentUser);
|
||||
|
||||
return { loginResult, currentUser };
|
||||
} catch (error) {
|
||||
console.error('Login failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Example 4: Update profile (authenticated call)
|
||||
async function updateProfile(profileData: any) {
|
||||
try {
|
||||
const updatedProfile = await pennyzoApi.updateUserProfile({
|
||||
first_name: profileData.firstName,
|
||||
last_name: profileData.lastName,
|
||||
mobile: profileData.mobile,
|
||||
industry: profileData.industry
|
||||
});
|
||||
|
||||
console.log('Profile updated successfully:', updatedProfile);
|
||||
return updatedProfile;
|
||||
} catch (error) {
|
||||
console.error('Profile update failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Example 5: Logout
|
||||
function logout() {
|
||||
pennyzoApi.logout();
|
||||
console.log('User logged out successfully');
|
||||
}
|
||||
|
||||
// Example 6: Error handling with the service
|
||||
async function demonstrateErrorHandling() {
|
||||
try {
|
||||
// Trying to access a protected endpoint without authentication
|
||||
await pennyzoApi.logout(); // Clear any existing token
|
||||
await pennyzoApi.getUserProfile(); // This should fail with 401
|
||||
} catch (error: any) {
|
||||
console.error('Expected error occurred:');
|
||||
console.error('Status:', error.status);
|
||||
console.error('Message:', error.message);
|
||||
console.error('Error code:', error.code);
|
||||
console.error('Details:', error.details);
|
||||
}
|
||||
}
|
||||
372
src/services/PennyzoApiService.ts
Normal file
372
src/services/PennyzoApiService.ts
Normal file
@@ -0,0 +1,372 @@
|
||||
import axios, { AxiosInstance, AxiosError, AxiosRequestConfig } from 'axios';
|
||||
import type {
|
||||
HealthResponse,
|
||||
RegisterRequest,
|
||||
RegisterResponse,
|
||||
LoginResponse,
|
||||
VerifyEmailResponse,
|
||||
ResendOtpResponse,
|
||||
ForgotPasswordResponse,
|
||||
PasswordResponse,
|
||||
UserMeResponse,
|
||||
UserProfile,
|
||||
UpdateUserProfileRequest,
|
||||
UpdateCompanyRequest,
|
||||
UpdateGstRegistrationRequest,
|
||||
UpgradeMembershipRequest,
|
||||
MembershipInfo,
|
||||
UserStats,
|
||||
PennyzoApiError,
|
||||
ErrorSchema
|
||||
} from '../types/api/pennyzo-api-types';
|
||||
|
||||
/**
|
||||
* PennyzoApiService - A comprehensive TypeScript class for handling all API interactions
|
||||
* with the Pennyzo General API
|
||||
*/
|
||||
export class PennyzoApiService {
|
||||
private apiClient: AxiosInstance;
|
||||
private accessToken: string | null = null;
|
||||
private readonly TOKEN_STORAGE_KEY = 'pennyzo_access_token';
|
||||
private readonly BASE_URL = 'https://api.pennyzo.com/api/v1/general';
|
||||
|
||||
constructor() {
|
||||
// Create Axios instance with base configuration
|
||||
this.apiClient = axios.create({
|
||||
baseURL: this.BASE_URL,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
// Load token from storage if available
|
||||
this.loadTokenFromStorage();
|
||||
|
||||
// Setup request interceptor for authentication
|
||||
this.setupRequestInterceptor();
|
||||
|
||||
// Setup response interceptor for error handling
|
||||
this.setupResponseInterceptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the request interceptor to attach the auth token to protected API calls
|
||||
*/
|
||||
private setupRequestInterceptor(): void {
|
||||
this.apiClient.interceptors.request.use((config) => {
|
||||
// If we have a token, add it to the request header
|
||||
if (this.accessToken) {
|
||||
config.headers.Authorization = `Bearer ${this.accessToken}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the response interceptor to handle errors consistently
|
||||
*/
|
||||
private setupResponseInterceptor(): void {
|
||||
this.apiClient.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error: AxiosError<ErrorSchema>) => {
|
||||
const apiError = this.createApiError(error);
|
||||
|
||||
// Handle 401 Unauthorized - Clear token and trigger authentication flow
|
||||
if (error.response?.status === 401) {
|
||||
this.clearToken();
|
||||
}
|
||||
|
||||
return Promise.reject(apiError);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a standardized error object from API errors
|
||||
*/
|
||||
private createApiError(error: AxiosError<ErrorSchema>): PennyzoApiError {
|
||||
const apiError: PennyzoApiError = new Error(
|
||||
error.response?.data?.error?.message || error.message
|
||||
);
|
||||
|
||||
apiError.name = 'PennyzoApiError';
|
||||
apiError.status = error.response?.status;
|
||||
apiError.code = error.response?.data?.error?.type;
|
||||
apiError.details = error.response?.data?.error?.details;
|
||||
apiError.originalError = error;
|
||||
|
||||
return apiError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the authentication token from local storage
|
||||
*/
|
||||
private loadTokenFromStorage(): void {
|
||||
if (typeof window !== 'undefined') {
|
||||
const token = localStorage.getItem(this.TOKEN_STORAGE_KEY);
|
||||
if (token) {
|
||||
this.accessToken = token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the authentication token in local storage
|
||||
*/
|
||||
private storeToken(token: string): void {
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem(this.TOKEN_STORAGE_KEY, token);
|
||||
this.accessToken = token;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the authentication token from local storage and memory
|
||||
*/
|
||||
private clearToken(): void {
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.removeItem(this.TOKEN_STORAGE_KEY);
|
||||
}
|
||||
this.accessToken = null;
|
||||
}
|
||||
|
||||
// ======== SYSTEM & REGISTRATION METHODS (PUBLIC) ========
|
||||
|
||||
/**
|
||||
* Check the health status of the API
|
||||
* GET /system/health
|
||||
*/
|
||||
async checkHealth(): Promise<HealthResponse> {
|
||||
const response = await this.apiClient.get<HealthResponse>('/system/health');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new user
|
||||
* POST /registration/register
|
||||
*/
|
||||
async registerUser(registrationData: RegisterRequest): Promise<RegisterResponse> {
|
||||
const response = await this.apiClient.post<RegisterResponse>(
|
||||
'/registration/register',
|
||||
registrationData
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// ======== AUTHENTICATION & VERIFICATION METHODS (PUBLIC) ========
|
||||
|
||||
/**
|
||||
* Login with email and password
|
||||
* POST /auth/login
|
||||
* Content-Type: application/x-www-form-urlencoded
|
||||
*/
|
||||
async login(email: string, password: string): Promise<LoginResponse> {
|
||||
const formData = new URLSearchParams();
|
||||
formData.append('username', email); // API uses username field for email
|
||||
formData.append('password', password);
|
||||
|
||||
const config: AxiosRequestConfig = {
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
};
|
||||
|
||||
const response = await this.apiClient.post<LoginResponse>(
|
||||
'/auth/login',
|
||||
formData,
|
||||
config
|
||||
);
|
||||
|
||||
// Store the token
|
||||
this.storeToken(response.data.access_token);
|
||||
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify user's email with OTP
|
||||
* POST /auth/verify-email
|
||||
*/
|
||||
async verifyEmail(email: string, otp_code: string): Promise<VerifyEmailResponse> {
|
||||
const response = await this.apiClient.post<VerifyEmailResponse>(
|
||||
'/auth/verify-email',
|
||||
{ email, otp_code }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resend verification OTP to email
|
||||
* POST /auth/resend-otp
|
||||
*/
|
||||
async resendVerificationOtp(email: string): Promise<ResendOtpResponse> {
|
||||
const response = await this.apiClient.post<ResendOtpResponse>(
|
||||
'/auth/resend-otp',
|
||||
{ email }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// ======== PASSWORD MANAGEMENT METHODS (PUBLIC/AUTHENTICATED) ========
|
||||
|
||||
/**
|
||||
* Request a password reset (forgot password)
|
||||
* POST /auth/forgot-password
|
||||
*/
|
||||
async forgotPassword(email: string): Promise<ForgotPasswordResponse> {
|
||||
const response = await this.apiClient.post<ForgotPasswordResponse>(
|
||||
'/auth/forgot-password',
|
||||
{ email }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset password using OTP
|
||||
* POST /auth/reset-password
|
||||
*/
|
||||
async resetPasswordWithOtp(
|
||||
email: string,
|
||||
otp_code: string,
|
||||
new_password: string
|
||||
): Promise<PasswordResponse> {
|
||||
const response = await this.apiClient.post<PasswordResponse>(
|
||||
'/auth/reset-password',
|
||||
{ email, otp_code, new_password }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change password (requires authentication)
|
||||
* POST /auth/change-password
|
||||
*/
|
||||
async changePassword(
|
||||
current_password: string,
|
||||
new_password: string
|
||||
): Promise<PasswordResponse> {
|
||||
const response = await this.apiClient.post<PasswordResponse>(
|
||||
'/auth/change-password',
|
||||
{ current_password, new_password }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// ======== USER & PROFILE MANAGEMENT METHODS (AUTHENTICATED) ========
|
||||
|
||||
/**
|
||||
* Get current user information
|
||||
* GET /auth/me
|
||||
*/
|
||||
async getCurrentUser(): Promise<UserMeResponse> {
|
||||
const response = await this.apiClient.get<UserMeResponse>('/auth/me');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user profile details
|
||||
* GET /users/profile
|
||||
*/
|
||||
async getUserProfile(): Promise<UserProfile> {
|
||||
const response = await this.apiClient.get<UserProfile>('/users/profile');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user profile information
|
||||
* PUT /users/profile
|
||||
*/
|
||||
async updateUserProfile(profileUpdateData: UpdateUserProfileRequest): Promise<UserProfile> {
|
||||
const response = await this.apiClient.put<UserProfile>(
|
||||
'/users/profile',
|
||||
profileUpdateData
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update company information
|
||||
* PUT /users/company
|
||||
*/
|
||||
async updateCompanyInfo(companyUpdateData: UpdateCompanyRequest): Promise<UserProfile> {
|
||||
const response = await this.apiClient.put<UserProfile>(
|
||||
'/users/company',
|
||||
companyUpdateData
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update GST registration information
|
||||
* PUT /users/gst-registration
|
||||
*/
|
||||
async updateGstRegistration(gstUpdateData: UpdateGstRegistrationRequest): Promise<UserProfile> {
|
||||
const response = await this.apiClient.put<UserProfile>(
|
||||
'/users/gst-registration',
|
||||
gstUpdateData
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// ======== MEMBERSHIP & STATS METHODS (AUTHENTICATED) ========
|
||||
|
||||
/**
|
||||
* Upgrade user membership
|
||||
* POST /users/upgrade-membership
|
||||
*/
|
||||
async upgradeMembership(membershipData: UpgradeMembershipRequest): Promise<UserProfile> {
|
||||
const response = await this.apiClient.post<UserProfile>(
|
||||
'/users/upgrade-membership',
|
||||
membershipData
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get membership information
|
||||
* GET /users/membership-info
|
||||
*/
|
||||
async getMembershipInfo(): Promise<MembershipInfo> {
|
||||
const response = await this.apiClient.get<MembershipInfo>('/users/membership-info');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user statistics
|
||||
* GET /users/stats
|
||||
*/
|
||||
async getUserStats(): Promise<UserStats> {
|
||||
const response = await this.apiClient.get<UserStats>('/users/stats');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// ======== SESSION MANAGEMENT ========
|
||||
|
||||
/**
|
||||
* Logout user by clearing the access token
|
||||
*/
|
||||
logout(): void {
|
||||
this.clearToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user is currently authenticated
|
||||
*/
|
||||
isAuthenticated(): boolean {
|
||||
return !!this.accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current access token (if any)
|
||||
*/
|
||||
getAccessToken(): string | null {
|
||||
return this.accessToken;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a singleton instance for easy import and usage
|
||||
export const pennyzoApi = new PennyzoApiService();
|
||||
|
||||
// Default export for convenient import
|
||||
export default PennyzoApiService;
|
||||
177
src/services/README.md
Normal file
177
src/services/README.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# Pennyzo API Service
|
||||
|
||||
A comprehensive TypeScript class for handling all API interactions with the Pennyzo General API.
|
||||
|
||||
## Features
|
||||
|
||||
- Complete JWT authentication lifecycle management
|
||||
- Automatic token handling for authenticated requests using Axios interceptors
|
||||
- Comprehensive error handling
|
||||
- TypeScript interfaces for request bodies and response payloads
|
||||
- Singleton pattern for easy usage throughout the application
|
||||
|
||||
## Installation
|
||||
|
||||
The service is already part of the Pennyzo Web project. It requires Axios, which is installed as a project dependency.
|
||||
|
||||
## API Methods
|
||||
|
||||
### System & Registration (Public)
|
||||
|
||||
```typescript
|
||||
// Check health status of the API
|
||||
const healthStatus = await pennyzoApi.checkHealth();
|
||||
|
||||
// Register a new user
|
||||
const registeredUser = await pennyzoApi.registerUser({
|
||||
first_name: "John",
|
||||
last_name: "Doe",
|
||||
email: "john.doe@example.com",
|
||||
// other required fields...
|
||||
});
|
||||
```
|
||||
|
||||
### Authentication & Verification (Public)
|
||||
|
||||
```typescript
|
||||
// Login a user
|
||||
const loginResult = await pennyzoApi.login("user@example.com", "password123");
|
||||
|
||||
// Verify email with OTP
|
||||
const verificationResult = await pennyzoApi.verifyEmail(
|
||||
"user@example.com",
|
||||
"123456"
|
||||
);
|
||||
|
||||
// Resend verification OTP
|
||||
const resendResult = await pennyzoApi.resendVerificationOtp("user@example.com");
|
||||
```
|
||||
|
||||
### Password Management (Public/Authenticated)
|
||||
|
||||
```typescript
|
||||
// Request password reset
|
||||
const forgotPasswordResult = await pennyzoApi.forgotPassword(
|
||||
"user@example.com"
|
||||
);
|
||||
|
||||
// Reset password with OTP
|
||||
const resetResult = await pennyzoApi.resetPasswordWithOtp(
|
||||
"user@example.com",
|
||||
"123456",
|
||||
"newPassword123"
|
||||
);
|
||||
|
||||
// Change password (authenticated)
|
||||
const changePasswordResult = await pennyzoApi.changePassword(
|
||||
"currentPassword123",
|
||||
"newPassword123"
|
||||
);
|
||||
```
|
||||
|
||||
### User & Profile Management (Authenticated)
|
||||
|
||||
```typescript
|
||||
// Get current user information
|
||||
const currentUser = await pennyzoApi.getCurrentUser();
|
||||
|
||||
// Get user profile
|
||||
const userProfile = await pennyzoApi.getUserProfile();
|
||||
|
||||
// Update user profile
|
||||
const updatedProfile = await pennyzoApi.updateUserProfile({
|
||||
first_name: "Updated",
|
||||
last_name: "Name",
|
||||
// other fields to update
|
||||
});
|
||||
|
||||
// Update company information
|
||||
const updatedCompany = await pennyzoApi.updateCompanyInfo({
|
||||
company_name: "New Company Name",
|
||||
industry: "Technology",
|
||||
});
|
||||
|
||||
// Update GST registration
|
||||
const updatedGst = await pennyzoApi.updateGstRegistration({
|
||||
gst_registered: true,
|
||||
gst_number: "GSTIN12345678",
|
||||
});
|
||||
```
|
||||
|
||||
### Membership & Stats (Authenticated)
|
||||
|
||||
```typescript
|
||||
// Upgrade membership
|
||||
const upgradedMembership = await pennyzoApi.upgradeMembership({
|
||||
plan_type: "ELITE",
|
||||
membership_type: "PAID",
|
||||
billing_cycle: "yearly",
|
||||
});
|
||||
|
||||
// Get membership information
|
||||
const membershipInfo = await pennyzoApi.getMembershipInfo();
|
||||
|
||||
// Get user statistics
|
||||
const userStats = await pennyzoApi.getUserStats();
|
||||
```
|
||||
|
||||
### Session Management
|
||||
|
||||
```typescript
|
||||
// Logout user (clears stored token)
|
||||
pennyzoApi.logout();
|
||||
|
||||
// Check if user is authenticated
|
||||
const isAuthenticated = pennyzoApi.isAuthenticated();
|
||||
|
||||
// Get the current access token (if any)
|
||||
const accessToken = pennyzoApi.getAccessToken();
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
The service handles errors gracefully and provides meaningful error objects with details:
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const profile = await pennyzoApi.getUserProfile();
|
||||
} catch (error) {
|
||||
console.error("Error status:", error.status);
|
||||
console.error("Error message:", error.message);
|
||||
console.error("Error code:", error.code);
|
||||
console.error("Error details:", error.details);
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation Details
|
||||
|
||||
- Uses Axios for all HTTP requests
|
||||
- Base URL is set to `https://api.pennyzo.com/api/v1/general`
|
||||
- Automatically attaches Bearer token to authenticated requests
|
||||
- Handles token storage in localStorage
|
||||
- Special handling for form-urlencoded content type (login endpoint)
|
||||
- Automatic 401 error handling to clear invalid tokens
|
||||
|
||||
## Usage Example
|
||||
|
||||
```typescript
|
||||
// Import the singleton instance
|
||||
import { pennyzoApi } from "../services";
|
||||
|
||||
// Use in async/await context
|
||||
async function fetchUserData() {
|
||||
try {
|
||||
// First authenticate
|
||||
await pennyzoApi.login("user@example.com", "password");
|
||||
|
||||
// Then make authenticated calls
|
||||
const profile = await pennyzoApi.getUserProfile();
|
||||
const stats = await pennyzoApi.getUserStats();
|
||||
|
||||
return { profile, stats };
|
||||
} catch (error) {
|
||||
console.error("API Error:", error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
```
|
||||
2
src/services/index.ts
Normal file
2
src/services/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { PennyzoApiService, pennyzoApi } from './PennyzoApiService';
|
||||
export { default } from './PennyzoApiService';
|
||||
85
src/types/api/pennyzo-api-types.ts
Normal file
85
src/types/api/pennyzo-api-types.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
// API Response and Request types for Pennyzo API Service
|
||||
import type { RegisterRequest, RegisterResponse,
|
||||
VerifyEmailRequest, VerifyEmailResponse,
|
||||
ResendOtpRequest, ResendOtpResponse,
|
||||
LoginResponse, UserMeResponse,
|
||||
UpdateCompanyRequest, UpdateGstRegistrationRequest,
|
||||
UpdateUserProfileRequest, UpgradeMembershipRequest,
|
||||
UserProfile, ErrorSchema, HealthResponse } from '../api';
|
||||
|
||||
// System & Registration Types
|
||||
export type { HealthResponse, RegisterRequest, RegisterResponse };
|
||||
|
||||
// Authentication & Verification Types
|
||||
export type { LoginResponse, VerifyEmailRequest, VerifyEmailResponse, ResendOtpRequest, ResendOtpResponse, UserMeResponse };
|
||||
|
||||
// Password Management Types
|
||||
export interface ForgotPasswordRequest {
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface ForgotPasswordResponse {
|
||||
message: string;
|
||||
email: string;
|
||||
expires_in: number;
|
||||
next_step?: string;
|
||||
}
|
||||
|
||||
export interface ResetPasswordRequest {
|
||||
email: string;
|
||||
otp_code: string;
|
||||
new_password: string;
|
||||
}
|
||||
|
||||
export interface ChangePasswordRequest {
|
||||
current_password: string;
|
||||
new_password: string;
|
||||
}
|
||||
|
||||
export interface PasswordResponse {
|
||||
message: string;
|
||||
}
|
||||
|
||||
// User & Profile Management Types
|
||||
export type { UserProfile, UpdateUserProfileRequest, UpdateCompanyRequest, UpdateGstRegistrationRequest };
|
||||
|
||||
// Membership & Stats Types
|
||||
export type { UpgradeMembershipRequest };
|
||||
|
||||
export interface MembershipInfo {
|
||||
id: number;
|
||||
user_id: number;
|
||||
membership_type: string;
|
||||
plan_type: string;
|
||||
is_paid: boolean;
|
||||
plan_start?: string;
|
||||
plan_end?: string;
|
||||
auto_renew?: boolean;
|
||||
payment_method_id?: string;
|
||||
billing_cycle?: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface UserStats {
|
||||
user_id: number;
|
||||
total_transactions: number;
|
||||
total_amount: number;
|
||||
current_month_transactions: number;
|
||||
current_month_amount: number;
|
||||
pending_invoices: number;
|
||||
pending_payments: number;
|
||||
document_count: number;
|
||||
last_activity_date: string;
|
||||
// Add other stats as per API response
|
||||
}
|
||||
|
||||
// Error Types
|
||||
export type { ErrorSchema };
|
||||
|
||||
export interface PennyzoApiError extends Error {
|
||||
status?: number;
|
||||
code?: string;
|
||||
details?: any;
|
||||
originalError?: any;
|
||||
}
|
||||
Reference in New Issue
Block a user