Skip to content

Commit

Permalink
feat(api): assemblies setup (#142)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jayllyz authored May 28, 2024
1 parent d7eddb1 commit bf5a7e0
Show file tree
Hide file tree
Showing 42 changed files with 726 additions and 75 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ coverage
out/
build
dist
tsconfig.tsbuildinfo

# Debug
npm-debug.log*
Expand Down
8 changes: 0 additions & 8 deletions apps/admin/app/(dashboard)/dashboard/users/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,6 @@ import AddUser from '@/app/ui/dashboard/users/AddUser';
import UsersList from '@/app/ui/dashboard/users/UsersList';
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@repo/ui/components/ui/card';
import { Input } from '@repo/ui/components/ui/input';
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from '@repo/ui/components/ui/pagination';
import { Table, TableBody, TableHead, TableHeader, TableRow } from '@repo/ui/components/ui/table';
import { Tabs, TabsContent } from '@repo/ui/components/ui/tabs';
import { useSearchParams } from 'next/navigation';
Expand Down
1 change: 0 additions & 1 deletion apps/admin/app/ui/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
PaginationNext,
PaginationPrevious,
} from '@repo/ui/components/ui/pagination';
import React from 'react';

interface Props {
page: number;
Expand Down
1 change: 0 additions & 1 deletion apps/admin/app/ui/dashboard/tournaments/TournamentRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { toast } from '@repo/ui/components/ui/sonner';
import { TableCell, TableRow } from '@repo/ui/components/ui/table';
import { MoreHorizontal } from 'lucide-react';
import Link from 'next/link';
import React from 'react';
import { useState } from 'react';

type Tournament = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import TournamentRow from '@/app/ui/dashboard/tournaments/TournamentRow';
import React from 'react';

type Tournament = {
id: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { format } from 'date-fns';
import { fr } from 'date-fns/locale';
import { Calendar as CalendarIcon, PlusCircle } from 'lucide-react';
import { useRouter } from 'next/navigation';
import type React from 'react';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { Form, FormControl, FormField, FormItem, FormMessage } from '@repo/ui/co
import { Input } from '@repo/ui/components/ui/input';
import { Label } from '@repo/ui/components/ui/label';
import { useRouter } from 'next/navigation';
import type React from 'react';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
DialogTrigger,
} from '@repo/ui/components/ui/dialog';
import { useRouter } from 'next/navigation';
import type React from 'react';
import { useState } from 'react';

interface DeleteMatchProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
DialogTrigger,
} from '@repo/ui/components/ui/dialog';
import { useRouter } from 'next/navigation';
import type React from 'react';
import { useState } from 'react';

type Round = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ import { TimePicker } from '@repo/ui/components/ui/time-picker';
import { cn } from '@repo/ui/lib/utils';
import { format } from 'date-fns';
import { fr } from 'date-fns/locale';
import { Calendar as CalendarIcon, PlusCircle } from 'lucide-react';
import { Calendar as CalendarIcon } from 'lucide-react';
import { useRouter } from 'next/navigation';
import type React from 'react';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { Form, FormControl, FormField, FormItem, FormMessage } from '@repo/ui/co
import { Input } from '@repo/ui/components/ui/input';
import { Label } from '@repo/ui/components/ui/label';
import { useRouter } from 'next/navigation';
import type React from 'react';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import EditMatch from '@/app/ui/dashboard/tournaments/matches/EditMatch';
import EditRound from '@/app/ui/dashboard/tournaments/matches/EditRound';
import { Separator } from '@repo/ui/components/ui/separator';
import { Crown } from 'lucide-react';
import type React from 'react';

type Round = {
id: number;
Expand Down
1 change: 0 additions & 1 deletion apps/admin/tsconfig.tsbuildinfo

This file was deleted.

2 changes: 1 addition & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@repo/typescript-config": "workspace:*",
"@types/node": "^20.12.12",
"@types/swagger-ui-dist": "^3.30.4",
"supabase": "^1.169.6",
"supabase": "^1.169.8",
"tsx": "^4.11.0",
"typescript": "^5.4.5",
"vitest": "^1.6.0"
Expand Down
232 changes: 232 additions & 0 deletions apps/api/src/handlers/assemblies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import { OpenAPIHono } from '@hono/zod-openapi';
import { supabase } from '../libs/supabase.js';
import { zodErrorHook } from '../libs/zodError.js';
import {
confirmMemberPresence,
createAssembly,
deleteAssembly,
getAllAssemblies,
getOneAssembly,
updateAssembly,
} from '../routes/assemblies.js';
import { checkRole } from '../utils/context.js';
import { getPagination } from '../utils/pagnination.js';
import type { Variables } from '../validators/general.js';

export const assemblies = new OpenAPIHono<{ Variables: Variables }>({
defaultHook: zodErrorHook,
});

assemblies.openapi(getOneAssembly, async (c) => {
const user = c.get('user');
const roles = user.roles;
await checkRole(roles, true);
const { id } = c.req.valid('param');

const { data, error } = await supabase
.from('ASSEMBLIES')
.select('*,attendees:ASSEMBLIES_ATTENDEES(users:USERS(id,first_name,last_name, email))')
.eq('id', id)
.single();

if (error || !data) {
return c.json({ error: 'Assembly not found' }, 404);
}

const format = {
id: data.id,
name: data.name,
description: data.description || null,
date: data.date,
location: data.location || null,
attendees: data.attendees
? data.attendees
.map((attendee) => attendee.users)
.filter(Boolean)
.flat()
: [],
lawsuit: data.lawsuit || null,
};

return c.json(format, 200);
});

assemblies.openapi(getAllAssemblies, async (c) => {
const user = c.get('user');
const roles = user.roles;
await checkRole(roles, true);
const { all, search, skip, take, date, location } = c.req.valid('query');

const query = supabase
.from('ASSEMBLIES')
.select('*, attendees:ASSEMBLIES_ATTENDEES(users:USERS(id,first_name,last_name, email))', { count: 'exact' })
.order('id', { ascending: true });

if (search) {
query.ilike('name', `%${search}%`);
}

if (date) {
query.eq('date', date);
}

if (location) {
query.eq('location.id', location);
}

if (!all) {
const { from, to } = getPagination(skip, take - 1);
query.range(from, to);
}

const { data, error, count } = await query;

if (error || !data) {
return c.json({ error: error.message }, 500);
}

const format = data.map((row) => ({
id: row.id,
name: row.name,
description: row.description || null,
date: row.date,
location: row.location || null,
attendees: row.attendees
? row.attendees
.map((attendee) => attendee.users)
.filter(Boolean)
.flat()
: [],
lawsuit: row.lawsuit || null,
}));

return c.json({ data: format, count: count || 0 }, 200);
});

assemblies.openapi(createAssembly, async (c) => {
const user = c.get('user');
const roles = user.roles;
await checkRole(roles, false);

const { name, description, date, location, lawsuit } = c.req.valid('json');

const { data, error } = await supabase
.from('ASSEMBLIES')
.insert({ name, description, date, location, lawsuit })
.select('*,location:ADDRESSES(*)')
.single();

if (error || !data) {
return c.json({ error: 'Failed to create assembly' }, 400);
}

const format = {
id: data.id,
name: data.name,
description: data.description || null,
date: data.date,
location: data.location || null,
lawsuit: data.lawsuit || null,
};

return c.json(format, 201);
});

assemblies.openapi(updateAssembly, async (c) => {
const user = c.get('user');
const roles = user.roles;
await checkRole(roles, false);

const { id } = c.req.valid('param');
const { name, description, date, location, lawsuit } = c.req.valid('json');

if (date && new Date(date) < new Date()) {
return c.json({ error: 'Date must be in the future' }, 400);
}

const { data: assembly, error: assemblyError } = await supabase.from('ASSEMBLIES').select('id').eq('id', id).single();

if (assemblyError || !assembly) {
return c.json({ error: 'Assembly not found' }, 404);
}

const { data, error } = await supabase
.from('ASSEMBLIES')
.update({ name, description, date, location, lawsuit })
.eq('id', id)
.select('*,location:ADDRESSES(*)')
.single();

if (error || !data) {
return c.json({ error: 'Failed to update assembly' }, 400);
}

const format = {
id: data.id,
name: data.name,
description: data.description || null,
date: data.date,
location: data.location || null,
lawsuit: data.lawsuit || null,
};

return c.json(format, 200);
});

assemblies.openapi(deleteAssembly, async (c) => {
const user = c.get('user');
const roles = user.roles;
await checkRole(roles, false);

const { id } = c.req.valid('param');

const { data: assembly, error: assemblyError } = await supabase.from('ASSEMBLIES').select('id').eq('id', id).single();

if (assemblyError || !assembly) {
return c.json({ error: 'Assembly not found' }, 404);
}

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

if (error) {
return c.json({ error: 'Failed to delete assembly' }, 500);
}

return c.json({ message: 'Assembly deleted' }, 200);
});

assemblies.openapi(confirmMemberPresence, async (c) => {
const user = c.get('user');
const roles = user.roles;
await checkRole(roles, false);

const { id, id_member } = c.req.valid('param');

const { data: assembly, error: assemblyError } = await supabase.from('ASSEMBLIES').select('id').eq('id', id).single();

if (assemblyError || !assembly) {
return c.json({ error: 'Assembly not found' }, 404);
}

const { data: member, error: memberError } = await supabase
.from('USERS')
.select('id, date_validity')
.eq('id', id_member)
.single();

if (memberError || !member) {
return c.json({ error: 'Member not found' }, 404);
}

if (member.date_validity && new Date(member.date_validity) < new Date()) {
return c.json({ error: 'Member subscription expired' }, 400);
}

const { error } = await supabase.from('ASSEMBLIES_ATTENDEES').insert({ id_assembly: id, id_user: id_member });

if (error) {
return c.json({ error: 'Failed to confirm member' }, 500);
}

return c.json({ message: 'Member confirmed' }, 200);
});
3 changes: 1 addition & 2 deletions apps/api/src/handlers/stripe.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { OpenAPIHono } from '@hono/zod-openapi';
import type { Context } from 'hono';
import Stripe from 'stripe';
import {
handleDonations,
Expand All @@ -18,7 +17,7 @@ export const stripe = new OpenAPIHono<{ Variables: Variables }>({
defaultHook: zodErrorHook,
});

stripe.openapi(webhook, async (context: Context) => {
stripe.openapi(webhook, async (context) => {
const STRIPE_SECRET_API_KEY = process.env.STRIPE_SECRET_API_KEY as string;
const STRIPE_WEBHOOK_SECRET = process.env.STRIPE_WEBHOOK_SECRET as string;
const stripe = new Stripe(STRIPE_SECRET_API_KEY);
Expand Down
2 changes: 0 additions & 2 deletions apps/api/src/handlers/tournaments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,8 +494,6 @@ tournaments.openapi(updateMatch, async (c) => {
])
.select('*, teams:TEAMS(id, name)');

console.log(dataTeams, errorTeams);

if (errorTeams || !dataTeams) {
return c.json({ error: 'Failed to update match' }, 500);
}
Expand Down
Loading

0 comments on commit bf5a7e0

Please sign in to comment.