forked from jamesp/sasa-membership
Basic frontend
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import axios from 'axios';
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: '/api/v1',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
// Add token to requests if available
|
||||
api.interceptors.request.use((config) => {
|
||||
const token = localStorage.getItem('token');
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
// Handle 401 errors
|
||||
api.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error.response?.status === 401) {
|
||||
localStorage.removeItem('token');
|
||||
window.location.href = '/login';
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default api;
|
||||
@@ -0,0 +1,66 @@
|
||||
import api from './api';
|
||||
|
||||
export interface LoginData {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface RegisterData {
|
||||
email: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
phone?: string;
|
||||
address?: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface ForgotPasswordData {
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface ResetPasswordData {
|
||||
token: string;
|
||||
new_password: string;
|
||||
}
|
||||
|
||||
class AuthService {
|
||||
async login(data: LoginData) {
|
||||
const response = await api.post('/auth/login-json', data);
|
||||
const { access_token } = response.data;
|
||||
this.setToken(access_token);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async register(data: RegisterData) {
|
||||
const response = await api.post('/auth/register', data);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async forgotPassword(data: ForgotPasswordData) {
|
||||
const response = await api.post('/auth/forgot-password', data);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async resetPassword(data: ResetPasswordData) {
|
||||
const response = await api.post('/auth/reset-password', data);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
logout() {
|
||||
localStorage.removeItem('token');
|
||||
}
|
||||
|
||||
getToken() {
|
||||
return localStorage.getItem('token');
|
||||
}
|
||||
|
||||
setToken(token: string) {
|
||||
localStorage.setItem('token', token);
|
||||
}
|
||||
|
||||
isAuthenticated() {
|
||||
return !!this.getToken();
|
||||
}
|
||||
}
|
||||
|
||||
export const authService = new AuthService();
|
||||
@@ -0,0 +1,197 @@
|
||||
import api from './api';
|
||||
|
||||
export interface RegisterData {
|
||||
email: string;
|
||||
password: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
phone?: string;
|
||||
address?: string;
|
||||
}
|
||||
|
||||
export interface LoginData {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface User {
|
||||
id: number;
|
||||
email: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
phone: string | null;
|
||||
address: string | null;
|
||||
role: string;
|
||||
is_active: boolean;
|
||||
created_at: string;
|
||||
last_login: string | null;
|
||||
}
|
||||
|
||||
export interface MembershipTier {
|
||||
id: number;
|
||||
name: string;
|
||||
description: string;
|
||||
annual_fee: number;
|
||||
benefits: string;
|
||||
is_active: boolean;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface Membership {
|
||||
id: number;
|
||||
user_id: number;
|
||||
tier_id: number;
|
||||
status: string;
|
||||
start_date: string;
|
||||
end_date: string;
|
||||
auto_renew: boolean;
|
||||
created_at: string;
|
||||
tier: MembershipTier;
|
||||
}
|
||||
|
||||
export interface Payment {
|
||||
id: number;
|
||||
user_id: number;
|
||||
membership_id: number | null;
|
||||
amount: number;
|
||||
payment_method: string;
|
||||
status: string;
|
||||
transaction_id: string | null;
|
||||
payment_date: string | null;
|
||||
notes: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface ForgotPasswordData {
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface ResetPasswordData {
|
||||
token: string;
|
||||
new_password: string;
|
||||
}
|
||||
|
||||
export interface MembershipCreateData {
|
||||
tier_id: number;
|
||||
start_date: string;
|
||||
end_date: string;
|
||||
auto_renew: boolean;
|
||||
}
|
||||
|
||||
export interface PaymentCreateData {
|
||||
amount: number;
|
||||
payment_method: string;
|
||||
membership_id?: number;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface PaymentUpdateData {
|
||||
status?: string;
|
||||
transaction_id?: string;
|
||||
payment_date?: string;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface MembershipUpdateData {
|
||||
tier_id?: number;
|
||||
status?: string;
|
||||
end_date?: string;
|
||||
auto_renew?: boolean;
|
||||
}
|
||||
|
||||
export const authService = {
|
||||
async register(data: RegisterData) {
|
||||
const response = await api.post('/auth/register', data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async login(data: LoginData) {
|
||||
const response = await api.post('/auth/login-json', data);
|
||||
localStorage.setItem('token', response.data.access_token);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async forgotPassword(data: ForgotPasswordData) {
|
||||
const response = await api.post('/auth/forgot-password', data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async resetPassword(data: ResetPasswordData) {
|
||||
const response = await api.post('/auth/reset-password', data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
logout() {
|
||||
localStorage.removeItem('token');
|
||||
},
|
||||
|
||||
isAuthenticated() {
|
||||
return !!localStorage.getItem('token');
|
||||
}
|
||||
};
|
||||
|
||||
export const userService = {
|
||||
async getCurrentUser(): Promise<User> {
|
||||
const response = await api.get('/users/me');
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async updateProfile(data: Partial<User>) {
|
||||
const response = await api.put('/users/me', data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async getAllUsers(): Promise<User[]> {
|
||||
const response = await api.get('/users/');
|
||||
return response.data;
|
||||
}
|
||||
};
|
||||
|
||||
export const membershipService = {
|
||||
async getMyMemberships(): Promise<Membership[]> {
|
||||
const response = await api.get('/memberships/my-memberships');
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async createMembership(data: MembershipCreateData): Promise<Membership> {
|
||||
const response = await api.post('/memberships/', data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async updateMembership(membershipId: number, data: MembershipUpdateData): Promise<Membership> {
|
||||
const response = await api.put(`/memberships/${membershipId}`, data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async getAllMemberships(): Promise<Membership[]> {
|
||||
const response = await api.get('/memberships/');
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async getTiers(): Promise<MembershipTier[]> {
|
||||
const response = await api.get('/tiers/');
|
||||
return response.data;
|
||||
}
|
||||
};
|
||||
|
||||
export const paymentService = {
|
||||
async getMyPayments(): Promise<Payment[]> {
|
||||
const response = await api.get('/payments/my-payments');
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async createPayment(data: PaymentCreateData): Promise<Payment> {
|
||||
const response = await api.post('/payments/', data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async updatePayment(paymentId: number, data: PaymentUpdateData): Promise<Payment> {
|
||||
const response = await api.put(`/payments/${paymentId}`, data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async getAllPayments(): Promise<Payment[]> {
|
||||
const response = await api.get('/payments/');
|
||||
return response.data;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user