Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions apps/user-fe/api/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Authentication related API calls
import { apiClient } from "./client";

interface LoginCredentials {
email: string;
password: string;
}

interface SignupData {
email: string;
password: string;
name: string;
}

interface OtpVerificationParams {
useremail: string;
otp: string;
device_id: string;
mydeviceid?: string;
mydeviceid2?: string;
}

export const authApi = {
login: async (credentials: LoginCredentials) => {
const response = await apiClient.post("/auth/login", credentials);
return response.data;
},

signup: async (data: SignupData) => {
const response = await apiClient.post("/auth/signup", data);
return response.data;
},

logout: async () => {
const response = await apiClient.post("/auth/logout");
return response.data;
},

verifyToken: async () => {
const response = await apiClient.get("/auth/verify");
return response.data;
},

sendOtp: async (phone: string) => {
const response = await apiClient.get(`/get/sendotp`, {
params: { phone },
});
return response.data;
},

resentOtp: async (phone: string) => {
const formData = new FormData();
formData.append("mobile", phone);
formData.append("type", "text");

const response = await apiClient.post(
`/post/resend_otp_with_call`,
formData
);
return response.data;
},

verifyOtp: async (params: OtpVerificationParams) => {
const response = await apiClient.get(`/get/otpverify`, {
params: params,
});
return response.data;
},
};
39 changes: 39 additions & 0 deletions apps/user-fe/api/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Base API client setup
import axios from "axios";

const API_BASE_URL =
process.env.NEXT_PUBLIC_API_URL || "https://indiasgotlatentapi.akamai.net.in";

export const apiClient = axios.create({
baseURL: API_BASE_URL,
headers: {
"Auth-Key": "appxapi",
},
});

// Request interceptor
apiClient.interceptors.request.use(
(config) => {
const token = localStorage.getItem("token");
if (token) {
config.headers.Authorization = `${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);

// Response interceptor
apiClient.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Handle unauthorized access
localStorage.removeItem("token");
window.location.href = "/login";
}
return Promise.reject(error);
}
);
39 changes: 39 additions & 0 deletions apps/user-fe/api/episodes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Episodes related API calls
import { apiClient } from "./client";
import { PaginatedResponse } from "./types";

export interface Episode {
id: string;
title: string;
thumbnail: string;
episodeNumber: number;
youtubeId: string;
isPremium: boolean;
}

export const episodesApi = {
getAll: async (page = 1, limit = 10) => {
const response = await apiClient.get<PaginatedResponse<Episode>>(
"/episodes",
{
params: { page, limit },
}
);
return response.data;
},

getById: async (id: string) => {
const response = await apiClient.get<Episode>(`/episodes/${id}`);
return response.data;
},

getPremiumEpisodes: async (page = 1, limit = 10) => {
const response = await apiClient.get<PaginatedResponse<Episode>>(
"/episodes/premium",
{
params: { page, limit },
}
);
return response.data;
},
};
37 changes: 37 additions & 0 deletions apps/user-fe/api/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Events related API calls
import { apiClient } from "./client";
import { PaginatedResponse } from "./types";

export interface Event {
id: string;
eventName: string;
date: string;
time: string;
venue: string;
location: string;
eventType: string;
ageRating: string;
reviews: number;
ticketPrice: number;
}

export const eventsApi = {
getAll: async (page = 1, limit = 10) => {
const response = await apiClient.get<PaginatedResponse<Event>>("/events", {
params: { page, limit },
});
return response.data;
},

getById: async (id: string) => {
const response = await apiClient.get<Event>(`/events/${id}`);
return response.data;
},

bookTicket: async (eventId: string, quantity: number) => {
const response = await apiClient.post(`/events/${eventId}/book`, {
quantity,
});
return response.data;
},
};
5 changes: 5 additions & 0 deletions apps/user-fe/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from "./auth";
export * from "./episodes";
export * from "./events";
export * from "./types";
export * from "./user";
37 changes: 37 additions & 0 deletions apps/user-fe/api/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Common types for API requests and responses
export interface ApiResponse<T> {
data: T;
message: string;
status: number;
}

export interface PaginatedResponse<T> {
data: T[];
total: number;
page: number;
limit: number;
}

export interface ErrorResponse {
message: string;
status: number;
}

export interface UserValidationResponse {
status: number;
message: string;
data: {
userid: string;
email: string;
phone: string;
info_1: string;
name: string;
username: string;
is_blank: boolean;
state: string;
app_category: string;
report_url: string;
cd: string;
is_tester: boolean;
};
}
34 changes: 34 additions & 0 deletions apps/user-fe/api/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { apiClient } from "./client";
import { UserValidationResponse } from "./types";

export const userApi = {
validateUser: async () => {
try {
const userId = localStorage.getItem("userId");
if (!userId) {
throw new Error("No user ID found");
}

const response = await apiClient.get<UserValidationResponse>(
"/get/get_user_dt",
{
params: { userid: userId },
}
);

if (response.data.status === 200) {
return response.data;
} else {
// If validation fails, clean up
localStorage.removeItem("token");
localStorage.removeItem("userId");
throw new Error("User validation failed");
}
} catch (error) {
// Clean up on any error
localStorage.removeItem("token");
localStorage.removeItem("userId");
throw error;
}
},
};
2 changes: 2 additions & 0 deletions apps/user-fe/app/_assets/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,5 @@ export const IMAGES = {
OtpGirl,
curtain,
};

export { playStore, mobile, appStore, Amic };
8 changes: 5 additions & 3 deletions apps/user-fe/app/_components/home/joinButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ export function JoinButton() {
"hover:opacity-90 transition-opacity w-fit shadow-[0_0_15px_rgba(170,130,61,0.3)]"
)}
>
<span className="text-neutral-950 text-lg font-semibold">
Join Latent+
</span>
<a href="/premium">
<span className="text-neutral-950 text-lg font-semibold">
Join Latent+
</span>
</a>
</button>
);
}
8 changes: 5 additions & 3 deletions apps/user-fe/app/_components/home/premiumFeature.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export function PremiumFeatures() {
];

return (
<div className="relative">
<div className="rounded-[24px] bg-[#1A1A1A] border border-[#aa823d]/20 p-12 relative">
<div className="mt-16 relative">
<div className="rounded-[24px] bg-[#1A1A1A] border border-[#aa823d]/20 p-12 relative shadow-[0px_0px_120px_5px_rgba(170,130,61,0.4)]">
{/* Glow effect */}
<div className="absolute inset-0 bg-[#aa823d] opacity-[0.03] blur-[100px]" />

Expand Down Expand Up @@ -45,7 +45,9 @@ export function PremiumFeatures() {
<div className="space-y-8 w-[480px] ml-auto">
{features.map((feature, index) => (
<div key={index} className="flex items-center gap-3">
<BadgeCheckIcon className="w-6 h-6 text-[#AA823D] flex-shrink-0" />
<div>
<BadgeCheckIcon className="w-6 h-6 text-[#AA823D] flex-shrink-0" />
</div>
<span
className={cn(
"text-neutral-50 text-2xl font-thin leading-10"
Expand Down
15 changes: 10 additions & 5 deletions apps/user-fe/app/_components/latentEpisodes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,36 @@ import { Carousel } from "./carousel";
const episodes = [
{
title: "India's Got Latent ft. Ashish Chanchlani | EP 1",
thumbnail: "https://files.vidstack.io/sprite-fight/poster.webp",
thumbnail:
"https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
episodeNumber: 1,
youtubeId: "Ry2sHFGQXzI",
},
{
title: "India's Got Latent ft. Tanmay Bhat | EP 2",
thumbnail: "https://files.vidstack.io/sprite-fight/poster.webp",
thumbnail:
"https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
episodeNumber: 2,
youtubeId: "Ry2sHFGQXzI",
},
{
title: "India's Got Latent ft. Zakir Khan | EP 3",
thumbnail: "https://files.vidstack.io/sprite-fight/poster.webp",
thumbnail:
"https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
episodeNumber: 3,
youtubeId: "Ry2sHFGQXzI",
},
{
title: "India's Got Latent ft. Harsh Gujral | EP 4",
thumbnail: "https://files.vidstack.io/sprite-fight/poster.webp",
thumbnail:
"https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
episodeNumber: 4,
youtubeId: "Ry2sHFGQXzI",
},
{
title: "India's Got Latent ft. Anubhav Bassi | EP 5",
thumbnail: "https://files.vidstack.io/sprite-fight/poster.webp",
thumbnail:
"https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
episodeNumber: 5,
youtubeId: "Ry2sHFGQXzI",
},
Expand Down
20 changes: 10 additions & 10 deletions apps/user-fe/app/_components/latentPlusEpisodes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,33 @@ export const premiumEpisodes = [
{
title:
"India's Got Latent ft. Ashish Chanchlani, Beer Biceps, Rebel Kid | EP 1",
thumbnail: "https://files.vidstack.io/sprite-fight/poster.webp",
thumbnail: "https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
slug: "episode-1",
videoUrl: "https://files.vidstack.io/sprite-fight/poster.webp",
videoUrl: "https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
},
{
title: "India's Got Latent ft. Tanmay Bhat, CarryMinati | EP 2",
thumbnail: "https://files.vidstack.io/sprite-fight/poster.webp",
thumbnail: "https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
slug: "episode-2",
videoUrl: "https://files.vidstack.io/sprite-fight/poster.webp",
videoUrl: "https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
},
{
title: "India's Got Latent ft. Zakir Khan, BB Ki Vines | EP 3",
thumbnail: "https://files.vidstack.io/sprite-fight/poster.webp",
thumbnail: "https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
slug: "episode-3",
videoUrl: "https://files.vidstack.io/sprite-fight/poster.webp",
videoUrl: "https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
},
{
title: "India's Got Latent ft. Harsh Gujral, Technical Guruji | EP 4",
thumbnail: "https://files.vidstack.io/sprite-fight/poster.webp",
thumbnail: "https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
slug: "episode-4",
videoUrl: "https://files.vidstack.io/sprite-fight/poster.webp",
videoUrl: "https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
},
{
title: "India's Got Latent ft. Anubhav Bassi, Flying Beast | EP 5",
thumbnail: "https://files.vidstack.io/sprite-fight/poster.webp",
thumbnail: "https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
slug: "episode-5",
videoUrl: "https://files.vidstack.io/sprite-fight/poster.webp",
videoUrl: "https://m.media-amazon.com/images/M/MV5BNDViYTM1MDUtZjZlZi00YTEyLWFiNmYtZGQ0Yjk0Mzk3MmY0XkEyXkFqcGc@._V1_.jpg",
},
];

Expand Down
Loading