Compare commits
5 Commits
2a71371683
...
c9f153c345
| Author | SHA1 | Date |
|---|---|---|
|
|
c9f153c345 | 2 weeks ago |
|
|
447b2125a8 | 2 weeks ago |
|
|
fbf4bdd55b | 2 weeks ago |
|
|
2899e1fd58 | 2 weeks ago |
|
|
b91f2d47bc | 2 weeks ago |
@ -0,0 +1,39 @@
|
||||
import { spawn } from 'child_process';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname, join } from 'path';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const proxies = [
|
||||
{ name: 'API', script: 'proxy-api.mjs' },
|
||||
{ name: 'Auth', script: 'proxy-auth.mjs' },
|
||||
];
|
||||
|
||||
const processes = [];
|
||||
|
||||
for (const proxy of proxies) {
|
||||
const proc = spawn('node', [join(__dirname, proxy.script)], {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
proc.on('error', (err) => {
|
||||
console.error(`[${proxy.name}] Failed to start:`, err);
|
||||
});
|
||||
|
||||
proc.on('exit', (code) => {
|
||||
console.log(`[${proxy.name}] Exited with code ${code}`);
|
||||
});
|
||||
|
||||
processes.push(proc);
|
||||
}
|
||||
|
||||
// Handle Ctrl+C
|
||||
process.on('SIGINT', () => {
|
||||
console.log('\nShutting down proxies...');
|
||||
for (const proc of processes) {
|
||||
proc.kill();
|
||||
}
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
console.log('All proxies started. Press Ctrl+C to stop.');
|
||||
@ -0,0 +1,108 @@
|
||||
import 'dotenv/config';
|
||||
import http from 'http';
|
||||
import https from 'https';
|
||||
|
||||
const TARGET = process.env.PROXY_API_TARGET;
|
||||
const PORT = process.env.PROXY_API_PORT;
|
||||
const LOCAL_ORIGIN = process.env.PROXY_LOCAL_ORIGIN;
|
||||
const PROD_ORIGIN = process.env.PROXY_PROD_ORIGIN;
|
||||
|
||||
if (!TARGET) throw new Error('PROXY_API_TARGET environment variable is required');
|
||||
if (!PORT) throw new Error('PROXY_API_PORT environment variable is required');
|
||||
if (!LOCAL_ORIGIN) throw new Error('PROXY_LOCAL_ORIGIN environment variable is required');
|
||||
if (!PROD_ORIGIN) throw new Error('PROXY_PROD_ORIGIN environment variable is required');
|
||||
|
||||
const parsedPort = parseInt(PORT, 10);
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
// Handle preflight OPTIONS requests
|
||||
if (req.method === 'OPTIONS') {
|
||||
res.setHeader('Access-Control-Allow-Origin', LOCAL_ORIGIN);
|
||||
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
||||
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH');
|
||||
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Timezone, X-Locale');
|
||||
res.writeHead(204);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
// Rewrite origin to match production so backend CORS accepts it
|
||||
const headers = { ...req.headers, host: TARGET };
|
||||
if (headers.origin === LOCAL_ORIGIN) {
|
||||
headers.origin = PROD_ORIGIN;
|
||||
}
|
||||
|
||||
const options = {
|
||||
hostname: TARGET,
|
||||
port: 443,
|
||||
path: req.url,
|
||||
method: req.method,
|
||||
headers,
|
||||
};
|
||||
|
||||
const proxyReq = https.request(options, (proxyRes) => {
|
||||
// Merge CORS headers with response headers
|
||||
const headers = { ...proxyRes.headers };
|
||||
headers['access-control-allow-origin'] = LOCAL_ORIGIN;
|
||||
headers['access-control-allow-credentials'] = 'true';
|
||||
|
||||
res.writeHead(proxyRes.statusCode, headers);
|
||||
proxyRes.pipe(res);
|
||||
});
|
||||
|
||||
proxyReq.on('error', (err) => {
|
||||
console.error('Proxy error:', err);
|
||||
res.writeHead(500);
|
||||
res.end('Proxy error');
|
||||
});
|
||||
|
||||
req.pipe(proxyReq);
|
||||
});
|
||||
|
||||
// Handle WebSocket upgrades for Socket.IO
|
||||
server.on('upgrade', (req, socket, head) => {
|
||||
// Rewrite origin to match production so backend CORS accepts it
|
||||
const headers = { ...req.headers, host: TARGET };
|
||||
if (headers.origin === LOCAL_ORIGIN) {
|
||||
headers.origin = PROD_ORIGIN;
|
||||
}
|
||||
|
||||
const options = {
|
||||
hostname: TARGET,
|
||||
port: 443,
|
||||
path: req.url,
|
||||
method: 'GET',
|
||||
headers,
|
||||
};
|
||||
|
||||
const proxyReq = https.request(options);
|
||||
|
||||
proxyReq.on('upgrade', (proxyRes, proxySocket, proxyHead) => {
|
||||
let response = 'HTTP/1.1 101 Switching Protocols\r\n' +
|
||||
'Upgrade: websocket\r\n' +
|
||||
'Connection: Upgrade\r\n' +
|
||||
`Sec-WebSocket-Accept: ${proxyRes.headers['sec-websocket-accept']}\r\n`;
|
||||
|
||||
// Forward compression extension if backend negotiated it
|
||||
if (proxyRes.headers['sec-websocket-extensions']) {
|
||||
response += `Sec-WebSocket-Extensions: ${proxyRes.headers['sec-websocket-extensions']}\r\n`;
|
||||
}
|
||||
|
||||
response += '\r\n';
|
||||
socket.write(response);
|
||||
|
||||
proxySocket.pipe(socket);
|
||||
socket.pipe(proxySocket);
|
||||
});
|
||||
|
||||
proxyReq.on('error', (err) => {
|
||||
console.error('WebSocket proxy error:', err);
|
||||
socket.end();
|
||||
});
|
||||
|
||||
proxyReq.end();
|
||||
});
|
||||
|
||||
server.listen(parsedPort, () => {
|
||||
console.log(`API Proxy running: localhost:${parsedPort} -> ${TARGET} (HTTP + WebSocket)`);
|
||||
});
|
||||
@ -0,0 +1,59 @@
|
||||
import 'dotenv/config';
|
||||
import http from 'http';
|
||||
import https from 'https';
|
||||
|
||||
const TARGET = process.env.PROXY_AUTH_TARGET;
|
||||
const PORT = process.env.PROXY_AUTH_PORT;
|
||||
const LOCAL_ORIGIN = process.env.PROXY_LOCAL_ORIGIN;
|
||||
|
||||
if (!TARGET) throw new Error('PROXY_AUTH_TARGET environment variable is required');
|
||||
if (!PORT) throw new Error('PROXY_AUTH_PORT environment variable is required');
|
||||
if (!LOCAL_ORIGIN) throw new Error('PROXY_LOCAL_ORIGIN environment variable is required');
|
||||
|
||||
const parsedPort = parseInt(PORT, 10);
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
// Handle preflight OPTIONS requests
|
||||
if (req.method === 'OPTIONS') {
|
||||
res.setHeader('Access-Control-Allow-Origin', LOCAL_ORIGIN);
|
||||
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
||||
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH');
|
||||
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Timezone, X-Locale');
|
||||
res.writeHead(204);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
const options = {
|
||||
hostname: TARGET,
|
||||
port: 443,
|
||||
path: req.url,
|
||||
method: req.method,
|
||||
headers: {
|
||||
...req.headers,
|
||||
host: TARGET,
|
||||
},
|
||||
};
|
||||
|
||||
const proxyReq = https.request(options, (proxyRes) => {
|
||||
// Copy response headers but add CORS
|
||||
const headers = { ...proxyRes.headers };
|
||||
headers['access-control-allow-origin'] = LOCAL_ORIGIN;
|
||||
headers['access-control-allow-credentials'] = 'true';
|
||||
|
||||
res.writeHead(proxyRes.statusCode, headers);
|
||||
proxyRes.pipe(res);
|
||||
});
|
||||
|
||||
proxyReq.on('error', (err) => {
|
||||
console.error('Proxy error:', err);
|
||||
res.writeHead(500);
|
||||
res.end('Proxy error');
|
||||
});
|
||||
|
||||
req.pipe(proxyReq);
|
||||
});
|
||||
|
||||
server.listen(parsedPort, () => {
|
||||
console.log(`Auth Proxy running: localhost:${parsedPort} -> ${TARGET}`);
|
||||
});
|
||||
@ -1,11 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import ClubProfileTab from './tabs/ClubProfileTab';
|
||||
|
||||
interface ClubDetailTabsProps {
|
||||
clubId: number;
|
||||
}
|
||||
|
||||
export default function ClubDetailTabs({ clubId }: ClubDetailTabsProps) {
|
||||
return <ClubProfileTab clubId={clubId} />;
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
import CompetitionDetailComponent from './CompetitionDetailComponent';
|
||||
|
||||
export default async function CompetitionDetailPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ club_id: string; competition_id: string }>;
|
||||
}) {
|
||||
const { club_id, competition_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
const competitionId = parseInt(competition_id, 10);
|
||||
|
||||
return <CompetitionDetailComponent clubId={clubId} competitionId={competitionId} />;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import CompetitionsPageComponent from './CompetitionsPageComponent';
|
||||
|
||||
export default async function CompetitionsPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ club_id: string }>;
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return <CompetitionsPageComponent clubId={clubId} />;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import SeriesListComponent from './SeriesListComponent';
|
||||
|
||||
export default async function SeriesPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ club_id: string }>;
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return <SeriesListComponent clubId={clubId} />;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import TemplatesPageComponent from './TemplatesPageComponent';
|
||||
|
||||
export default async function TemplatesPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ club_id: string }>;
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return <TemplatesPageComponent clubId={clubId} />;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import CourtsComponent from './CourtsComponent';
|
||||
|
||||
export default async function CourtsPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ club_id: string }>
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return <CourtsComponent clubId={clubId} />;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import CreditsManagementComponent from './CreditsManagementComponent';
|
||||
|
||||
export default async function CreditsManagementPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ club_id: string }>;
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return <CreditsManagementComponent clubId={clubId} />;
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
import AdminAuthGuard from '@/src/components/AdminAuthGuard';
|
||||
import ClubDetailHeader from '@/src/components/ClubDetailHeader';
|
||||
|
||||
export default async function ClubDetailLayout({
|
||||
children,
|
||||
params,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
params: Promise<{ club_id: string }>;
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return (
|
||||
<AdminAuthGuard>
|
||||
<ClubDetailHeader clubId={clubId}>
|
||||
{children}
|
||||
</ClubDetailHeader>
|
||||
</AdminAuthGuard>
|
||||
);
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import MembersManagementComponent from './MembersManagementComponent';
|
||||
|
||||
export default async function MembersManagementPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ club_id: string }>;
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return <MembersManagementComponent clubId={clubId} />;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import ClubDetailTabs from './ClubDetailTabs';
|
||||
|
||||
export default async function AdminClubDetailPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ club_id: string }>
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return <ClubDetailTabs clubId={clubId} />;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import MembershipPlansComponent from './MembershipPlansComponent';
|
||||
|
||||
export default async function MembershipPlansPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ club_id: string }>;
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return <MembershipPlansComponent clubId={clubId} />;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import FacilitySettingsComponent from './FacilitySettingsComponent';
|
||||
|
||||
export default async function FacilitySettingsPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ club_id: string }>;
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return <FacilitySettingsComponent clubId={clubId} />;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import SlotDefinitionsComponent from './SlotDefinitionsComponent';
|
||||
|
||||
export default async function SlotDefinitionsPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ club_id: string }>;
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return <SlotDefinitionsComponent clubId={clubId} />;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import SlotInstancesComponent from './SlotInstancesComponent';
|
||||
|
||||
export default async function SlotInstancesPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ club_id: string }>;
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return <SlotInstancesComponent clubId={clubId} />;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import TransfersManagementComponent from './TransfersManagementComponent';
|
||||
|
||||
export default async function TransfersManagementPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ club_id: string }>;
|
||||
}) {
|
||||
const { club_id } = await params;
|
||||
const clubId = parseInt(club_id, 10);
|
||||
|
||||
return <TransfersManagementComponent clubId={clubId} />;
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
'use client';
|
||||
|
||||
import FacilityProfileTab from './tabs/FacilityProfileTab';
|
||||
|
||||
interface FacilityDetailTabsProps {
|
||||
facilityId: number;
|
||||
}
|
||||
|
||||
export default function FacilityDetailTabs({ facilityId }: FacilityDetailTabsProps) {
|
||||
return <FacilityProfileTab facilityId={facilityId} />;
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
import CompetitionDetailComponent from './CompetitionDetailComponent';
|
||||
|
||||
export default async function CompetitionDetailPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ facility_id: string; competition_id: string }>;
|
||||
}) {
|
||||
const { facility_id, competition_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
const competitionId = parseInt(competition_id, 10);
|
||||
|
||||
return <CompetitionDetailComponent facilityId={facilityId} competitionId={competitionId} />;
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import CompetitionsPageComponent from './CompetitionsPageComponent';
|
||||
|
||||
export default async function CompetitionsPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ facility_id: string }>;
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return <CompetitionsPageComponent facilityId={facilityId} />;
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import SeriesListComponent from './SeriesListComponent';
|
||||
|
||||
export default async function SeriesPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ facility_id: string }>;
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return <SeriesListComponent facilityId={facilityId} />;
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import TemplatesPageComponent from './TemplatesPageComponent';
|
||||
|
||||
export default async function TemplatesPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ facility_id: string }>;
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return <TemplatesPageComponent facilityId={facilityId} />;
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import CourtsComponent from './CourtsComponent';
|
||||
|
||||
export default async function CourtsPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ facility_id: string }>
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return <CourtsComponent facilityId={facilityId} />;
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import CreditsManagementComponent from './CreditsManagementComponent';
|
||||
|
||||
export default async function CreditsManagementPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ facility_id: string }>;
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return <CreditsManagementComponent facilityId={facilityId} />;
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
import AdminAuthGuard from '@/src/components/AdminAuthGuard';
|
||||
import FacilityDetailHeader from '@/src/components/FacilityDetailHeader';
|
||||
|
||||
export default async function FacilityDetailLayout({
|
||||
children,
|
||||
params,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
params: Promise<{ facility_id: string }>;
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return (
|
||||
<AdminAuthGuard>
|
||||
<FacilityDetailHeader facilityId={facilityId}>
|
||||
{children}
|
||||
</FacilityDetailHeader>
|
||||
</AdminAuthGuard>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import MembersManagementComponent from './MembersManagementComponent';
|
||||
|
||||
export default async function MembersManagementPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ facility_id: string }>;
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return <MembersManagementComponent facilityId={facilityId} />;
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import FacilityDetailTabs from './FacilityDetailTabs';
|
||||
|
||||
export default async function AdminClubDetailPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ facility_id: string }>
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return <FacilityDetailTabs facilityId={facilityId} />;
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import MembershipPlansComponent from './MembershipPlansComponent';
|
||||
|
||||
export default async function MembershipPlansPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ facility_id: string }>;
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return <MembershipPlansComponent facilityId={facilityId} />;
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import FacilitySettingsComponent from './FacilitySettingsComponent';
|
||||
|
||||
export default async function FacilitySettingsPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ facility_id: string }>;
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return <FacilitySettingsComponent facilityId={facilityId} />;
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import SlotDefinitionsComponent from './SlotDefinitionsComponent';
|
||||
|
||||
export default async function SlotDefinitionsPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ facility_id: string }>;
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return <SlotDefinitionsComponent facilityId={facilityId} />;
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import SlotInstancesComponent from './SlotInstancesComponent';
|
||||
|
||||
export default async function SlotInstancesPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ facility_id: string }>;
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return <SlotInstancesComponent facilityId={facilityId} />;
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import TransfersManagementComponent from './TransfersManagementComponent';
|
||||
|
||||
export default async function TransfersManagementPage({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ facility_id: string }>;
|
||||
}) {
|
||||
const { facility_id } = await params;
|
||||
const facilityId = parseInt(facility_id, 10);
|
||||
|
||||
return <TransfersManagementComponent facilityId={facilityId} />;
|
||||
}
|
||||
@ -1,10 +1,10 @@
|
||||
import AdminClubsList from './AdminClubsList';
|
||||
import AdminFacilitiesList from './AdminFacilitiesList';
|
||||
import AdminAuthGuard from '@/src/components/AdminAuthGuard';
|
||||
|
||||
export default async function AdminClubsPage() {
|
||||
return (
|
||||
<AdminAuthGuard>
|
||||
<AdminClubsList />
|
||||
<AdminFacilitiesList />
|
||||
</AdminAuthGuard>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue