Skip to content

Commit

Permalink
Merge pull request #50 from Praashh/feat-event
Browse files Browse the repository at this point in the history
[feat]: logger, add order, queues, trade summary & add events
  • Loading branch information
Praashh authored Oct 19, 2024
2 parents 6e6329f + 99c8a35 commit cceeb9c
Show file tree
Hide file tree
Showing 30 changed files with 741 additions and 308 deletions.
138 changes: 70 additions & 68 deletions apps/client/app/(lobby)/events/page.tsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,85 @@
"use server";
import { EventCard } from "@/components/landing/Home/EventCard";
import { getEvents } from "@/actions/Event/getEvents";
import { TEvent } from "@opinix/types";

const Page = () => {
const events = [
{
icon: "/assets/event1.png",
traders: 31823,
question: "Centre to constitute the 8th Pay Commission?",
yesValue: 4,
noValue: 6,
},
{
icon: "/assets/event2.png",
traders: 6410,
question:
"Kane Williamson to announce his retirement from international T20 cricket?",
yesValue: 4.5,
noValue: 5.5,
},
{
icon: "/assets/event3.png",
traders: 7467,
question:
"Tesla to open their first showroom in India by the end of 2024?",
yesValue: 2.5,
noValue: 7.5,
},
{
icon: "/assets/event4.png",
traders: 1367,
question: "Red Bull Racing to win the F1 Constructors Championship 2024?",
yesValue: 5,
noValue: 5,
},
{
icon: "/assets/event1.png",
traders: 31823,
question: "Centre to constitute the 8th Pay Commission?",
yesValue: 4,
noValue: 6,
},
{
icon: "/assets/event2.png",
traders: 6410,
question:
"Kane Williamson to announce his retirement from international T20 cricket?",
yesValue: 4.5,
noValue: 5.5,
},
{
icon: "/assets/event3.png",
traders: 7467,
question:
"Tesla to open their first showroom in India by the end of 2024?",
yesValue: 2.5,
noValue: 7.5,
},
{
icon: "/assets/event4.png",
traders: 1367,
question: "Red Bull Racing to win the F1 Constructors Championship 2024?",
yesValue: 5,
noValue: 5,
},
];
const Page = async () => {
const events: TEvent[] = await getEvents();
// const events = [
// {
// icon: "/assets/event1.png",
// traders: 31823,
// question: "Centre to constitute the 8th Pay Commission?",
// yesValue: 4,
// noValue: 6,
// },
// {
// icon: "/assets/event2.png",
// traders: 6410,
// question:
// "Kane Williamson to announce his retirement from international T20 cricket?",
// yesValue: 4.5,
// noValue: 5.5,
// },
// {
// icon: "/assets/event3.png",
// traders: 7467,
// question:
// "Tesla to open their first showroom in India by the end of 2024?",
// yesValue: 2.5,
// noValue: 7.5,
// },
// {
// icon: "/assets/event4.png",
// traders: 1367,
// question: "Red Bull Racing to win the F1 Constructors Championship 2024?",
// yesValue: 5,
// noValue: 5,
// },
// {
// icon: "/assets/event1.png",
// traders: 31823,
// question: "Centre to constitute the 8th Pay Commission?",
// yesValue: 4,
// noValue: 6,
// },
// {
// icon: "/assets/event2.png",
// traders: 6410,
// question:
// "Kane Williamson to announce his retirement from international T20 cricket?",
// yesValue: 4.5,
// noValue: 5.5,
// },
// {
// icon: "/assets/event3.png",
// traders: 7467,
// question:
// "Tesla to open their first showroom in India by the end of 2024?",
// yesValue: 2.5,
// noValue: 7.5,
// },
// {
// icon: "/assets/event4.png",
// traders: 1367,
// question: "Red Bull Racing to win the F1 Constructors Championship 2024?",
// yesValue: 5,
// noValue: 5,
// },
// ];

return (
<>
<div className="w-full lg:w-full p-8 flex justify-center items-center">
<div className="w-full lg:w-full p-8 flex justify-center items-center">
{/* Events Grid Section */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 gap-8 lg:w-1/2 w-full mt-8 lg:mt-0 overflow-y-auto">
{events.map((event, index) => (
<EventCard key={index} {...event} />
<EventCard key={index} event={event} />
))}
</div>
</div>

</>
);
};


export default Page;
export default Page;
32 changes: 32 additions & 0 deletions apps/client/app/actions/event.action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"use server";

import prisma from "@repo/db/client";

import { withServerActionAsyncCatcher } from "@/lib/async-catch";
import { ServerActionReturnType } from "../types/api";
import { ErrorHandler } from "@/lib/error";

import { SuccessResponse } from "@/lib/success";

export const getEvents = withServerActionAsyncCatcher<
null,
ServerActionReturnType
>(async () => {
let events = await prisma.event.findMany({
select: {
eventId: true,
title: true,
slug: true,
quantity: true,
},
});
if (!events) {
throw new ErrorHandler("No events found", "NOT_FOUND");
}

return new SuccessResponse(
"Events fetched successfully",
200,
events
).serialize();
});
44 changes: 44 additions & 0 deletions apps/client/app/config/error.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
export const ERROR_NAME = {
UNAUTHORIZED: "Unauthorized access",
INTERNAL_SERVER_ERROR: "Internal server error",
BAD_REQUEST: "Bad request",
NOT_FOUND: "Resource not found",
FORBIDDEN: "Access forbidden",
CONFLICT: "Resource conflict",
UNPROCESSABLE_ENTITY: "Unprocessable entity",
TOO_MANY_REQUESTS: "Too many requests",
SERVICE_UNAVAILABLE: "Service unavailable",
GATEWAY_TIMEOUT: "Gateway timeout",
VALIDATION_ERROR: "Validation error",
AUTHENTICATION_FAILED: "Authentication failed",
INSUFFICIENT_PERMISSIONS: "Insufficient permissions",
REQUEST_TIMEOUT: "Request timeout",
UNSUPPORTED_MEDIA_TYPE: "Unsupported media type",
METHOD_NOT_ALLOWED: "Method not allowed",
DATABASE_ERROR: "Database error",
NETWORK_ERROR: "Network error",
RESOURCE_GONE: "Resource gone",
PRECONDITION_FAILED: "Precondition failed",
};
export const ERROR_CODE = {
UNAUTHORIZED: 401,
INTERNAL_SERVER_ERROR: 500,
BAD_REQUEST: 400,
NOT_FOUND: 404,
FORBIDDEN: 403,
CONFLICT: 409,
UNPROCESSABLE_ENTITY: 422,
TOO_MANY_REQUESTS: 429,
SERVICE_UNAVAILABLE: 503,
GATEWAY_TIMEOUT: 504,
VALIDATION_ERROR: 422,
AUTHENTICATION_FAILED: 401,
INSUFFICIENT_PERMISSIONS: 403,
REQUEST_TIMEOUT: 408,
UNSUPPORTED_MEDIA_TYPE: 415,
METHOD_NOT_ALLOWED: 405,
DATABASE_ERROR: 500,
NETWORK_ERROR: 502,
RESOURCE_GONE: 410,
PRECONDITION_FAILED: 412,
};
6 changes: 6 additions & 0 deletions apps/client/app/types/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ErrorResponseType } from "@/lib/error";
import { SuccessResponseType } from "@/lib/success";

export type ServerActionReturnType<T = unknown> =
| SuccessResponseType<T>
| ErrorResponseType;
44 changes: 23 additions & 21 deletions apps/client/components/landing/Home/EventCard.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,37 @@
import Image from "next/image";
import { TEvent } from "@opinix/types";

interface EventCardProps {
icon: string;
traders: number;
question: string;
yesValue: number;
noValue: number;
}

export const EventCard = ({
icon,
traders,
question,
yesValue,
noValue,
}: EventCardProps) => (
export const EventCard = ({ event }: { event: TEvent }) => (
<div className="rounded-lg shadow-lg p-4 flex flex-col justify-between bg-white">
<div className="flex flex-col mb-2">
<Image src={icon} alt="Event icon" className="w-10 h-10 mr-4" width={200} height={200}/>
<Image
src={"/assets/event1.png"}
alt="Event icon"
className="w-10 h-10 mr-4"
width={200}
height={200}
/>
<div className="flex mt-2">
<Image src="/assets/trade-icon.png" alt="" className="w-5 h-5" width={200} height={200}/>
<div className="text-gray-500 text-xs mt-0.5">{traders} traders</div>
<Image
src="/assets/trade-icon.png"
alt=""
className="w-5 h-5"
width={200}
height={200}
/>
<div className="text-gray-500 text-xs mt-0.5">
{event.traders} traders
</div>
</div>
</div>
<h3 className="font-semibold mb-4">{question}</h3>
<h3 className="font-semibold mb-4">{event.title}</h3>
{/* TODO: change the min_bet and max_bet with yes or no values ( 19th oct ) */}
<div className="flex justify-between">
<button className="bg-blue-100 text-blue-600 px-6 py-2 rounded font-bold">
Yes ₹{yesValue}
Yes ₹{event.min_bet}
</button>
<button className="bg-red-100 text-red-600 px-6 py-2 rounded font-bold">
No ₹{noValue}
No ₹{event.max_bet}
</button>
</div>
</div>
Expand Down
14 changes: 14 additions & 0 deletions apps/client/lib/async-catch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { standardizeApiError } from "./error";
type withServerActionAsyncCatcherType<T, R> = (args: T) => Promise<R>;

export function withServerActionAsyncCatcher<T, R>(
serverAction: withServerActionAsyncCatcherType<T, R>
): withServerActionAsyncCatcherType<T, R> {
return async (args: T): Promise<R> => {
try {
return await serverAction(args);
} catch (error) {
return standardizeApiError(error) as R;
}
};
}
65 changes: 65 additions & 0 deletions apps/client/lib/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { ERROR_NAME, ERROR_CODE } from "@/app/config/error.config";
import { ZodError } from "zod";
import { generateErrorMessage } from "zod-error";
export type ErrorResponseType = {
name: string;
message: string;
code: number;
status: false;
error?: any;
};
class ErrorHandler extends Error {
status: false;
error?: any;
code: number;
constructor(message: string, code: keyof typeof ERROR_CODE, error?: any) {
super(message);
this.status = false;
this.error = error;
this.code = ERROR_CODE[code];
this.name = ERROR_NAME[code];
}
}

function standardizeApiError(error: unknown): ErrorResponseType {
if (error instanceof ErrorHandler) {
return {
name: error.name,
message: error.message,
code: error.code,
status: false,
error: error.error,
};
}
if (error instanceof ZodError) {
return {
name: error.name,
message: generateErrorMessage(error.issues, {
maxErrors: 2,
delimiter: {
component: ": ",
},
message: {
enabled: true,
label: "",
},
path: {
enabled: false,
},
code: {
enabled: false,
},
}),
code: ERROR_CODE.UNPROCESSABLE_ENTITY,
status: false,
};
}
return {
name: ERROR_NAME.INTERNAL_SERVER_ERROR,
message:
"We're sorry for the inconvenience. Please report this issue to our support team ",
code: ERROR_CODE.INTERNAL_SERVER_ERROR,
status: false,
};
}
export { ErrorHandler, standardizeApiError };
Loading

0 comments on commit cceeb9c

Please sign in to comment.