Skip to content

Commit

Permalink
Api Integration (#61)
Browse files Browse the repository at this point in the history
* Added API endpoints
  • Loading branch information
JeetJani-11 authored Jul 26, 2024
1 parent adfa30f commit e0d1ed0
Show file tree
Hide file tree
Showing 12 changed files with 995 additions and 1 deletion.
292 changes: 292 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
"@types/react-dom": "^18",
"autoprefixer": "^10.4.19",
"postcss": "^8",
"supabase": "^1.187.3",
"tailwindcss": "^3.4.1",
"typescript": "^5"
}
}
}
74 changes: 74 additions & 0 deletions src/app/api/v1/create/event/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/utils/supabase/server";
import { Tables } from "@/types/supabase";

function validateEvent(event: Tables<"events">): {
valid: boolean;
message?: string;
} {
if (!event.name) {
return { valid: false, message: "Event name is required." };
}
if (!event.date || isNaN(Date.parse(event.date))) {
return {
valid: false,
message: "Event date is required and must be a valid date",
};
}
// Add more validations as needed
return { valid: true };
}

export async function POST(request: NextRequest): Promise<NextResponse> {
try {
const supabase = createClient();
const {
data: { user },
error: userError,
} = await supabase.auth.getUser();
if (userError || !user) {
return NextResponse.json(
{ success: false, message: "Unauthorized" },
{ status: 401 }
);
}
const isAdmin = await supabase.from("users").select("admin").eq("id", user.id);
if (isAdmin.error || !isAdmin.data || isAdmin.data.length === 0 || !isAdmin.data[0].admin) {
return NextResponse.json(
{ success: false, message: "Unauthorized" },
{ status: 401 }
);
}
const body = await request.json();
const { event }: { event: Tables<"events"> } = body;
event.creator = user.id;
const validation = validateEvent(event);
if (!validation.valid) {
return NextResponse.json(
{ success: false, message: validation.message },
{ status: 400 }
);
}

const { data, error } = await supabase
.from("events")
.insert([event])
.select();
if (error) {
throw new Error(error.message);
}
if (!data || data.length === 0) {
throw new Error("Failed to create event");
}
return NextResponse.json({
success: true,
message: "Event created successfully",
id: data[0].id,
});
} catch (error: any) {
return NextResponse.json(
{ success: false, message: error.message },
{ status: 500 }
);
}
}
64 changes: 64 additions & 0 deletions src/app/api/v1/delete/event/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/utils/supabase/server";
import { Tables } from "@/types/supabase";

export async function DELETE(request: NextRequest): Promise<NextResponse> {
try {
const supabase = createClient();
const {
data: { user },
error: userError,
} = await supabase.auth.getUser();
if (userError || !user) {
return NextResponse.json(
{ success: false, message: "Unauthorized" },
{ status: 401 }
);
}
const isAdmin = await supabase.from("users").select("admin").eq("id", user.id);
if (isAdmin.error || !isAdmin.data || isAdmin.data.length === 0 || !isAdmin.data[0].admin) {
return NextResponse.json(
{ success: false, message: "Unauthorized" },
{ status: 401 }
);
}
const url = new URL(request.url);
const id = url.searchParams.get("id");

if (!id) {
return NextResponse.json(
{ success: false, message: "Invalid or missing event ID" },
{ status: 400 }
);
}

const { data: event, error: eventError } = await supabase
.from("events")
.select("id")
.eq("id", id)
.single();

if (eventError) {
return NextResponse.json(
{ success: false, message: "Event not found" },
{ status: 404 }
);
}

const { error } = await supabase.from("events").delete().eq("id", id);

if (error) {
throw new Error(error.message);
}

return NextResponse.json({
success: true,
message: "Event deleted successfully",
});
} catch (error: any) {
return NextResponse.json(
{ success: false, message: error.message },
{ status: 500 }
);
}
}
63 changes: 63 additions & 0 deletions src/app/api/v1/get/blog/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/utils/supabase/server";

export async function GET(request: NextRequest): Promise<NextResponse> {
try {
const supabase = createClient();
const url = new URL(request.url);
const id = url.searchParams.get('id');
if (!id) {
return NextResponse.json(
{ success: false, message: 'Missing blog ID' },
{ status: 400 }
);
}

const { data: blog, error: blogError } = await supabase
.from('blogs')
.select('*')
.eq('id', id)
.single();

if (blogError || !blog) {
return NextResponse.json(
{ success: false, message: 'Blog not found' },
{ status: 404 }
);
}

const posterUrl = `${process.env.SUPABASE_STORAGE_URL}/web_data/images/${id}/poster`;
const blogFileUrl = `${process.env.SUPABASE_STORAGE_URL}/web_data/blogs/${id}/blog`;

const { data: images, error: imagesError } = await supabase
.storage
.from('web_data')
.list(`images/${id}/`);

if (imagesError) {
return NextResponse.json(
{ success: false, message: 'Error fetching images' },
{ status: 500 }
);
}

const imageUrls = images.map(image => `${process.env.SUPABASE_STORAGE_URL}/web_data/blogs/${id}/images/${image.name}`);


return NextResponse.json({
success: true,
message: 'Blog retrieved successfully',
blog: {
...blog,
posterUrl,
blogFileUrl,
images: imageUrls
}
});
} catch (error: any) {
return NextResponse.json(
{ success: false, message: error.message },
{ status: 500 }
);
}
}
70 changes: 70 additions & 0 deletions src/app/api/v1/get/blogs/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/utils/supabase/server";

export async function GET(request: NextRequest): Promise<NextResponse> {
try {
const supabase = createClient();

const url = new URL(request.url);
const limit = url.searchParams.get('limit');
const page = url.searchParams.get('page');

const limitNumber = limit ? parseInt(limit) : 5;
const pageNumber = page ? parseInt(page) : 1;

if (pageNumber < 1 || limitNumber < 1) {
return NextResponse.json(
{ success: false, message: 'Page and limit must be greater than 0' },
{ status: 400 }
);
}

const offset = (pageNumber - 1) * limitNumber;

const { data: blogs, error: blogsError } = await supabase
.from('blogs')
.select('*')
.range(offset, offset + limitNumber - 1);

if (blogsError) {
throw new Error(blogsError.message);
}


const blogPromises = blogs.map(async (blog) => {
const posterUrl = `${process.env.SUPABASE_STORAGE_URL}/web_data/images/${blog.id}/poster`;
const blogFileUrl = `${process.env.SUPABASE_STORAGE_URL}/web_data/blogs/${blog.id}/blog`;

const { data: images, error: imagesError } = await supabase
.storage
.from('web_data')
.list(`images/${blog.id}`);

if (imagesError) {
throw new Error(imagesError.message);
}

const imageUrls = images.map(image => `${process.env.SUPABASE_STORAGE_URL}/web_data/images/${blog.id}/${image.name}`);

return {
...blog,
posterUrl,
blogFileUrl,
images: imageUrls
};
});

const blogsWithAssets = await Promise.all(blogPromises);

return NextResponse.json({
success: true,
message: 'Blogs retrieved successfully',
blogs: blogsWithAssets,
});
} catch (error: any) {
return NextResponse.json(
{ success: false, message: error.message },
{ status: 500 }
);
}
}
43 changes: 43 additions & 0 deletions src/app/api/v1/get/event/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/utils/supabase/server";

export async function GET(request: NextRequest): Promise<NextResponse> {
try {
const supabase = createClient();

const url = new URL(request.url);
const id = url.searchParams.get('id');

if (!id) {
return NextResponse.json(
{ success: false, message: 'Event ID is required' },
{ status: 400 }
);
}

const { data: event, error: eventError } = await supabase
.from('events')
.select('*')
.eq('id', id)
.single();

if (eventError) {
return NextResponse.json(
{ success: false, message: 'Event not found' },
{ status: 404 }
);
}

return NextResponse.json({
success: true,
message: 'Event retrieved successfully',
event: event,
});
} catch (error: any) {
return NextResponse.json(
{ success: false, message: error.message },
{ status: 500 }
);
}
}
38 changes: 38 additions & 0 deletions src/app/api/v1/get/events/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// /api/v1/get/events/?category=upcoming&limit=10&page=1
import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/utils/supabase/server";

export async function GET(request: NextRequest) {
try {
const supabase = createClient();
const { searchParams } = new URL(request.url);
const category = searchParams.get("category") || "";
const limit = parseInt(searchParams.get("limit") || "5", 10);
const page = parseInt(searchParams.get("page") || "1", 10);

const offset = (page - 1) * limit;

let query = supabase
.from("events")
.select("*")
.range(offset, offset + limit - 1);

if (category.toLocaleLowerCase() === "upcoming") {
query = query.gt("date", new Date().toISOString());
}else if (category.toLocaleLowerCase() === "past") {
query = query.lt("date", new Date().toISOString());
}else if (category.toLocaleLowerCase() === "ongoing") {
query = query.eq("date", new Date().toISOString());
}

const { data, error } = await query;

if (error) {
throw new Error(error.message);
}

return NextResponse.json(data);
} catch (error) {
return NextResponse.error();
}
}
Loading

1 comment on commit e0d1ed0

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for iiitvcc ready!

✅ Preview
https://iiitvcc-5v9dwj7ue-iiitv-coding-clubs-projects.vercel.app

Built with commit e0d1ed0.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.