fix: Docker build and runtime fixes

- Fix duplicate 'signature' variable in webhooks.ts
- Add Prisma binary target for Alpine Linux
- Fix tsconfig path alias (@/* -> ./src/*)
- Add missing next-themes dependency
- Add build args for NEXT_PUBLIC_* env vars
- Fix SSR issues with zustand and providers
- Add providers-wrapper with dynamic ssr:false import
- Add SSL certs and public dir for nginx
- Update Dockerfiles for proper Prisma engine handling
This commit is contained in:
2026-04-15 14:16:27 -04:00
parent a1572d327f
commit 2388873e7a
17 changed files with 3414 additions and 150 deletions
+3 -3
View File
@@ -1,7 +1,7 @@
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';
import { Providers } from '@/components/providers';
import { ProvidersWrapper } from '@/components/providers-wrapper';
import { Toaster } from 'sonner';
const inter = Inter({ subsets: ['latin'] });
@@ -19,10 +19,10 @@ export default function RootLayout({
return (
<html lang="en" suppressHydrationWarning>
<body className={inter.className}>
<Providers>
<ProvidersWrapper>
{children}
<Toaster position="top-right" />
</Providers>
</ProvidersWrapper>
</body>
</html>
);
+2
View File
@@ -1,5 +1,7 @@
'use client';
export const dynamic = 'force-dynamic';
import { useEffect, useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { authApi } from '@/lib/api';
@@ -0,0 +1,13 @@
'use client';
import dynamic from 'next/dynamic';
import { ReactNode } from 'react';
const DynamicProviders = dynamic(
() => import('./providers').then((mod) => ({ default: mod.Providers })),
{ ssr: false }
);
export function ProvidersWrapper({ children }: { children: ReactNode }) {
return <DynamicProviders>{children}</DynamicProviders>;
}
+10 -20
View File
@@ -1,5 +1,4 @@
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
export interface User {
id: string;
@@ -21,22 +20,13 @@ interface AppState {
logout: () => void;
}
export const useStore = create<AppState>()(
persist(
(set) => ({
user: null,
token: null,
isAuthenticated: false,
setUser: (user) => set({ user, isAuthenticated: !!user }),
setToken: (token) => set({ token }),
logout: () => {
localStorage.removeItem('token');
set({ user: null, token: null, isAuthenticated: false });
},
}),
{
name: 'coop-credits-storage',
partialize: (state) => ({ user: state.user, token: state.token }),
}
)
);
export const useStore = create<AppState>()((set) => ({
user: null,
token: null,
isAuthenticated: false,
setUser: (user) => set({ user, isAuthenticated: !!user }),
setToken: (token) => set({ token }),
logout: () => {
set({ user: null, token: null, isAuthenticated: false });
},
}));