Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add member area layout #160

Merged
merged 7 commits into from
Jun 4, 2024
Merged
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
1 change: 0 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ NEXT_PUBLIC_ATHLONIX_STORAGE_URL=
SUPABASE_DOMAIN=
ATHLONIX_API_URL=
NEXT_PUBLIC_API_URL=

STRIPE_API_KEY=sk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
3 changes: 2 additions & 1 deletion apps/admin/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ ENV NEXT_PUBLIC_ATHLONIX_STORAGE_URL ${NEXT_PUBLIC_ATHLONIX_STORAGE_URL}
COPY --from=pruner --chown=node:node /app/out/full/ ./

RUN pnpm turbo run build --filter admin && \
pnpm prune --prod
pnpm prune --prod && \
pnpm --filter admin deploy --prod --ignore-scripts ./out

FROM base AS dev
WORKDIR /app
Expand Down
2 changes: 1 addition & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"dependencies": {
"@hono/node-server": "^1.11.2",
"@hono/swagger-ui": "^0.2.2",
"@hono/zod-openapi": "0.14.1",
"@hono/zod-openapi": "0.14.2",
"@hono/zod-validator": "^0.2.2",
"@repo/types": "workspace:*",
"@supabase/supabase-js": "^2.43.4",
Expand Down
3 changes: 2 additions & 1 deletion apps/client/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ ENV NEXT_PUBLIC_ATHLONIX_STORAGE_URL ${NEXT_PUBLIC_ATHLONIX_STORAGE_URL}
COPY --from=pruner --chown=node:node /app/out/full/ ./

RUN pnpm turbo run build --filter client && \
pnpm prune --prod
pnpm prune --prod && \
pnpm --filter client deploy --prod --ignore-scripts ./out

FROM base AS dev
WORKDIR /app
Expand Down
75 changes: 75 additions & 0 deletions apps/client/app/(auth)/(members)/members/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import '@repo/ui/globals.css';
import { FileSearch, Flame, Home, LineChart, MessageSquareMore, Trophy, Users } from 'lucide-react';
import Link from 'next/link';

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}): JSX.Element {
return (
<html lang="en">
<body className="min-h-screen bg-background font-sans antialiased">
<div className="grid min-h-screen w-full md:grid-cols-[220px_1fr] lg:grid-cols-[280px_1fr]">
<div className="hidden border-r bg-muted/40 md:block">
<div className="flex h-full max-h-screen flex-col gap-2">
<div className="flex h-14 items-center border-b px-4 lg:h-[60px] lg:px-6">
<Link href="/" className="flex items-center gap-2 font-semibold">
<Flame className="h-6 w-6 text-primary" />
<span className="">Escape membre Athlonix</span>
</Link>
</div>
<div className="flex-1">
<nav className="grid items-start px-2 text-sm font-medium lg:px-4">
<Link
href="/members"
className="flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary"
>
<Home className="h-4 w-4" />
Accueil
</Link>
<Link
href="/members/activities"
className="flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary"
>
<Users className="h-4 w-4" />
Activités
</Link>
<Link
href="/members/tournaments"
className="flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary"
>
<Trophy className="h-4 w-4" />
Tournois
</Link>
<Link
href="/members/chat"
className="flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary"
>
<MessageSquareMore className="h-4 w-4" />
Messagerie
</Link>
<Link
href="/members/documents"
className="flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary"
>
<FileSearch className="h-4 w-4" />
Documents
</Link>
<Link
href="/members/votes"
className="flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary"
>
<LineChart className="h-4 w-4" />
Votes
</Link>
</nav>
</div>
</div>
</div>
<div className="flex flex-col h-full">{children}</div>
</div>
</body>
</html>
);
}
12 changes: 12 additions & 0 deletions apps/client/app/(auth)/(members)/members/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function Page(): JSX.Element {
return (
<div className="container mx-auto py-12 px-4 md:px-6">
<h1 className="text-3xl font-bold mb-8">Bienvenue sur la page des membres</h1>
{
// todo: add content
}
</div>
);
}

export default Page;
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use client';
import type { Vote } from '@/app/lib/type/Votes';
import { type User, checkSubscription } from '@/app/lib/user/utils';
import { getAllVotes } from '@/app/lib/votes/utils';
import { Badge } from '@repo/ui/components/ui/badge';
import { Button } from '@repo/ui/components/ui/button';
import { Card } from '@repo/ui/components/ui/card';
import { Loader2 } from 'lucide-react';
import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';

const Icons = {
Expand All @@ -15,20 +17,29 @@ export default function ListVotes() {
const [votes, setVotes] = useState<Vote[]>([]);
const [loading, setLoading] = useState(true);
const [filter, setFilter] = useState<'all' | 'ongoing' | 'finished' | 'not_started'>('all');
const [subscriptionChecked, setSubscriptionChecked] = useState(false);
const router = useRouter();

useEffect(() => {
async function fetchData() {
if (!subscriptionChecked) {
const user = JSON.parse(localStorage.getItem('user') as string) as User;
if (!checkSubscription(user)) {
return router.push('/');
}
setSubscriptionChecked(true);
}
try {
const result = await getAllVotes();
setVotes(result);
setVotes(result.data);
setLoading(false);
} catch (error) {
setLoading(false);
}
}

fetchData();
}, []);
}, [subscriptionChecked, router]);

const filteredVotes = () => {
switch (filter) {
Expand Down
2 changes: 1 addition & 1 deletion apps/client/app/lib/user/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function getUserInfo(): Promise<User> {
if (!response.ok) {
throw new Error('Failed to fetch user info');
}
const user = await response.json();
const user = (await response.json()) as User;
localStorage.setItem('user', JSON.stringify(user));
return user;
}
Expand Down
2 changes: 1 addition & 1 deletion apps/client/app/lib/votes/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Vote } from '../type/Votes';

export async function getAllVotes(): Promise<Vote[]> {
export async function getAllVotes(): Promise<{ data: Vote[]; count: number }> {
const API_URL = process.env.NEXT_PUBLIC_API_URL;
const response = await fetch(`${API_URL}/polls?all=true`, {
headers: { Authorization: `Bearer ${localStorage.getItem('access_token')}` },
Expand Down
15 changes: 12 additions & 3 deletions apps/client/app/ui/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Image from 'next/image';
import Link from 'next/link';
import { useEffect, useState } from 'react';
import type React from 'react';
import { getUserAvatar } from '../lib/user/utils';
import { type User, checkSubscription, getUserAvatar } from '../lib/user/utils';

interface LinkProp {
name: string;
Expand Down Expand Up @@ -38,10 +38,14 @@ function LogoutUser() {

export const NavBar: React.FC<NavBarProps> = ({ links }) => {
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
const [user, setUser] = useState<User>();

useEffect(() => {
const user = localStorage.getItem('user');
setIsAuthenticated(user !== null);
const user = localStorage.getItem('user') as unknown as User;
setUser(user);
if (user) {
setIsAuthenticated(true);
}
}, []);

const navBarElements = links.map((link) => {
Expand Down Expand Up @@ -80,6 +84,11 @@ export const NavBar: React.FC<NavBarProps> = ({ links }) => {
<AvatarFallback className="bg-slate-400">{getUserAvatar()}</AvatarFallback>
</Avatar>
</Link>
{user !== undefined && checkSubscription(user) && (
<Button className="w-[120px]" asChild>
<Link href="/members">Espace membre</Link>
</Button>
)}
<Button className="w-[120px] bg-red-900">
<Link href={''} onClick={() => LogoutUser()}>
Se déconnecter
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"private": true,
"scripts": {
"clean": "turbo clean && rm -rf node_modules/ .turbo/ pnpm-lock.yaml",
"build": "turbo build",
"dev": "turbo dev",
"test": "turbo test",
"build": "turbo build --env-mode=loose",
"dev": "turbo dev --env-mode=loose",
"test": "turbo test --env-mode=loose",
"lint": "biome check --write",
"lint:check": "biome ci",
"types:check": "turbo types:check",
Expand All @@ -17,7 +17,7 @@
"@repo/biome-config": "workspace:*",
"@repo/supabase": "workspace:*",
"@repo/typescript-config": "workspace:*",
"turbo": "^1.13.3"
"turbo": "^2.0.1"
},
"packageManager": "pnpm@9.1.4",
"engines": {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"devDependencies": {
"@repo/biome-config": "workspace:*",
"@repo/typescript-config": "workspace:*",
"@turbo/gen": "^1.13.3",
"@turbo/gen": "^2.0.1",
"@types/node": "^20.14.1",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
Expand Down
Loading
Loading