Compare commits
2 Commits
7441d1ac58
...
main_old
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ed77dd471 | ||
|
|
94ea44c66e |
12
package.json
12
package.json
@@ -6,7 +6,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev --host 0.0.0.0",
|
"dev": "vite dev --host 0.0.0.0",
|
||||||
"build": "vite build && tsc --noEmit",
|
"build": "vite build && tsc --noEmit",
|
||||||
"start": "vite start"
|
"start": "node .output/server/index.mjs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hello-pangea/dnd": "^18.0.1",
|
"@hello-pangea/dnd": "^18.0.1",
|
||||||
@@ -21,15 +21,15 @@
|
|||||||
"@svgmoji/noto": "^3.2.0",
|
"@svgmoji/noto": "^3.2.0",
|
||||||
"@tanstack/react-query": "^5.66.0",
|
"@tanstack/react-query": "^5.66.0",
|
||||||
"@tanstack/react-query-devtools": "^5.66.0",
|
"@tanstack/react-query-devtools": "^5.66.0",
|
||||||
"@tanstack/react-router": "^1.130.12",
|
"@tanstack/react-router": "1.130.12",
|
||||||
"@tanstack/react-router-devtools": "^1.130.13",
|
"@tanstack/react-router-devtools": "1.130.13",
|
||||||
"@tanstack/react-router-with-query": "^1.130.12",
|
"@tanstack/react-router-with-query": "1.130.12",
|
||||||
"@tanstack/react-start": "^1.130.15",
|
"@tanstack/react-start": "1.130.15",
|
||||||
"@tanstack/react-virtual": "^3.13.12",
|
|
||||||
"@tiptap/pm": "^3.4.3",
|
"@tiptap/pm": "^3.4.3",
|
||||||
"@tiptap/react": "^3.4.3",
|
"@tiptap/react": "^3.4.3",
|
||||||
"@tiptap/starter-kit": "^3.4.3",
|
"@tiptap/starter-kit": "^3.4.3",
|
||||||
"@types/ioredis": "^4.28.10",
|
"@types/ioredis": "^4.28.10",
|
||||||
|
"dotenv": "^17.2.2",
|
||||||
"embla-carousel-react": "^8.6.0",
|
"embla-carousel-react": "^8.6.0",
|
||||||
"framer-motion": "^12.23.12",
|
"framer-motion": "^12.23.12",
|
||||||
"ioredis": "^5.7.0",
|
"ioredis": "^5.7.0",
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ import { routeTree } from "./routeTree.gen";
|
|||||||
import { DefaultCatchBoundary } from "../components/DefaultCatchBoundary";
|
import { DefaultCatchBoundary } from "../components/DefaultCatchBoundary";
|
||||||
import { defaultHeaderConfig } from "@/features/core/hooks/use-router-config";
|
import { defaultHeaderConfig } from "@/features/core/hooks/use-router-config";
|
||||||
|
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
|
||||||
export function createRouter() {
|
export function createRouter() {
|
||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ export const ServerRoute = createServerFileRoute('/api/spotify/token').methods({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh access token
|
|
||||||
const tokenResponse = await fetch('https://accounts.spotify.com/api/token', {
|
const tokenResponse = await fetch('https://accounts.spotify.com/api/token', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -46,7 +45,6 @@ export const ServerRoute = createServerFileRoute('/api/spotify/token').methods({
|
|||||||
|
|
||||||
const tokens = await tokenResponse.json()
|
const tokens = await tokenResponse.json()
|
||||||
|
|
||||||
// Return new tokens
|
|
||||||
return new Response(
|
return new Response(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
access_token: tokens.access_token,
|
access_token: tokens.access_token,
|
||||||
|
|||||||
@@ -72,7 +72,8 @@ export const ServerRoute = createServerFileRoute('/api/teams/upload-logo')
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!team.players.map(p => p.id).includes(context.userId) && !isAdmin)
|
const user = await pbAdmin.getPlayerByAuthId(context.userAuthId)
|
||||||
|
if (!team.players.map(p => p.id).includes(user!.id) && !isAdmin)
|
||||||
return new Response('Unauthorized', { status: 403 });
|
return new Response('Unauthorized', { status: 403 });
|
||||||
|
|
||||||
logger.info('Uploading team logo', {
|
logger.info('Uploading team logo', {
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { Box, Container, Flex, Loader, useComputedColorScheme } from "@mantine/core";
|
import { Box, Container, Flex, Loader, useComputedColorScheme } from "@mantine/core";
|
||||||
import { PropsWithChildren, Suspense, useEffect } from "react";
|
import { PropsWithChildren, Suspense, useEffect, useRef } from "react";
|
||||||
import { Drawer as VaulDrawer } from "vaul";
|
import { Drawer as VaulDrawer } from "vaul";
|
||||||
import styles from "./styles.module.css";
|
import styles from "./styles.module.css";
|
||||||
import FullScreenLoader from "../full-screen-loader";
|
|
||||||
|
|
||||||
interface DrawerProps extends PropsWithChildren {
|
interface DrawerProps extends PropsWithChildren {
|
||||||
title?: string;
|
title?: string;
|
||||||
@@ -17,6 +16,7 @@ const Drawer: React.FC<DrawerProps> = ({
|
|||||||
onChange,
|
onChange,
|
||||||
}) => {
|
}) => {
|
||||||
const colorScheme = useComputedColorScheme("light");
|
const colorScheme = useComputedColorScheme("light");
|
||||||
|
const contentRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const appElement = document.querySelector(".app") as HTMLElement;
|
const appElement = document.querySelector(".app") as HTMLElement;
|
||||||
@@ -59,11 +59,31 @@ const Drawer: React.FC<DrawerProps> = ({
|
|||||||
};
|
};
|
||||||
}, [opened, colorScheme]);
|
}, [opened, colorScheme]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!opened || !contentRef.current) return;
|
||||||
|
|
||||||
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
|
if (contentRef.current) {
|
||||||
|
const drawerContent = contentRef.current.closest('[data-vaul-drawer-wrapper]');
|
||||||
|
if (drawerContent) {
|
||||||
|
(drawerContent as HTMLElement).style.height = 'auto';
|
||||||
|
(drawerContent as HTMLElement).offsetHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resizeObserver.observe(contentRef.current);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
resizeObserver.disconnect();
|
||||||
|
};
|
||||||
|
}, [opened, children]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VaulDrawer.Root open={opened} onOpenChange={onChange}>
|
<VaulDrawer.Root open={opened} onOpenChange={onChange}>
|
||||||
<VaulDrawer.Portal>
|
<VaulDrawer.Portal>
|
||||||
<VaulDrawer.Overlay className={styles.drawerOverlay} />
|
<VaulDrawer.Overlay className={styles.drawerOverlay} />
|
||||||
<VaulDrawer.Content className={styles.drawerContent} aria-describedby="drawer">
|
<VaulDrawer.Content className={styles.drawerContent} aria-describedby="drawer" ref={contentRef}>
|
||||||
<Container flex={1} p="md">
|
<Container flex={1} p="md">
|
||||||
<Box
|
<Box
|
||||||
mb="sm"
|
mb="sm"
|
||||||
@@ -74,7 +94,7 @@ const Drawer: React.FC<DrawerProps> = ({
|
|||||||
mr="auto"
|
mr="auto"
|
||||||
style={{ borderRadius: "9999px" }}
|
style={{ borderRadius: "9999px" }}
|
||||||
/>
|
/>
|
||||||
<Container mah="fit-content" mx="auto" maw="28rem" px={0}>
|
<Container mx="auto" maw="28rem" px={0}>
|
||||||
<VaulDrawer.Title>{title}</VaulDrawer.Title>
|
<VaulDrawer.Title>{title}</VaulDrawer.Title>
|
||||||
<Suspense fallback={
|
<Suspense fallback={
|
||||||
<Flex justify='center' align='center' w='100%' h={400}>
|
<Flex justify='center' align='center' w='100%' h={400}>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { PropsWithChildren, useCallback } from "react";
|
|||||||
import { useIsMobile } from "@/hooks/use-is-mobile";
|
import { useIsMobile } from "@/hooks/use-is-mobile";
|
||||||
import Drawer from "./drawer";
|
import Drawer from "./drawer";
|
||||||
import Modal from "./modal";
|
import Modal from "./modal";
|
||||||
import { Box, ScrollArea } from "@mantine/core";
|
import { ScrollArea } from "@mantine/core";
|
||||||
|
|
||||||
interface SheetProps extends PropsWithChildren {
|
interface SheetProps extends PropsWithChildren {
|
||||||
title?: string;
|
title?: string;
|
||||||
@@ -29,7 +29,7 @@ const Sheet: React.FC<SheetProps> = ({ title, children, opened, onChange }) => {
|
|||||||
scrollbars="y"
|
scrollbars="y"
|
||||||
type="scroll"
|
type="scroll"
|
||||||
>
|
>
|
||||||
<Box mah="70vh">{children}</Box>
|
{children}
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</SheetComponent>
|
</SheetComponent>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,10 +11,13 @@
|
|||||||
border-top-left-radius: 20px;
|
border-top-left-radius: 20px;
|
||||||
border-top-right-radius: 20px;
|
border-top-right-radius: 20px;
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
height: fit-content;
|
height: auto !important;
|
||||||
|
min-height: fit-content;
|
||||||
|
max-height: 100dvh;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
transition: height 0.2s ease-out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ function SwipeableTabs({
|
|||||||
const activeSlideRef = slideRefs.current[activeTab];
|
const activeSlideRef = slideRefs.current[activeTab];
|
||||||
if (!activeSlideRef) return;
|
if (!activeSlideRef) return;
|
||||||
|
|
||||||
let timeoutId: number;
|
let timeoutId: any;
|
||||||
const resizeObserver = new ResizeObserver(() => {
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
timeoutId = setTimeout(updateHeight, 16);
|
timeoutId = setTimeout(updateHeight, 16);
|
||||||
|
|||||||
@@ -438,7 +438,6 @@ export const SpotifyProvider: React.FC<PropsWithChildren> = ({ children }) => {
|
|||||||
activeDevice,
|
activeDevice,
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
// Capture/Resume state
|
|
||||||
capturedState,
|
capturedState,
|
||||||
isCaptureLoading,
|
isCaptureLoading,
|
||||||
isResumeLoading,
|
isResumeLoading,
|
||||||
@@ -453,11 +452,9 @@ export const SpotifyProvider: React.FC<PropsWithChildren> = ({ children }) => {
|
|||||||
getDevices,
|
getDevices,
|
||||||
setActiveDevice,
|
setActiveDevice,
|
||||||
refreshPlaybackState,
|
refreshPlaybackState,
|
||||||
// Capture/Resume methods
|
|
||||||
capturePlaybackState,
|
capturePlaybackState,
|
||||||
resumePlaybackState,
|
resumePlaybackState,
|
||||||
clearCapturedState,
|
clearCapturedState,
|
||||||
// Search
|
|
||||||
searchTracks,
|
searchTracks,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ export const useMe = () => {
|
|||||||
const errorData = error?.response?.data;
|
const errorData = error?.response?.data;
|
||||||
if (errorData?.error === "SESSION_REFRESH_REQUIRED") {
|
if (errorData?.error === "SESSION_REFRESH_REQUIRED") {
|
||||||
const currentUrl = window.location.pathname + window.location.search;
|
const currentUrl = window.location.pathname + window.location.search;
|
||||||
|
console.log('redirecting 3')
|
||||||
window.location.href = `/refresh-session?redirect=${encodeURIComponent(currentUrl)}`;
|
window.location.href = `/refresh-session?redirect=${encodeURIComponent(currentUrl)}`;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ class PocketBaseAdminClient {
|
|||||||
public authPromise: Promise<void>;
|
public authPromise: Promise<void>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
console.log('Environment variables loaded:', {
|
||||||
|
POCKETBASE_URL: process.env.POCKETBASE_URL,
|
||||||
|
POCKETBASE_ADMIN_EMAIL: process.env.POCKETBASE_ADMIN_EMAIL,
|
||||||
|
POCKETBASE_ADMIN_PASSWORD: process.env.POCKETBASE_ADMIN_PASSWORD,
|
||||||
|
});
|
||||||
this.pb = new PocketBase(process.env.POCKETBASE_URL);
|
this.pb = new PocketBase(process.env.POCKETBASE_URL);
|
||||||
|
|
||||||
this.pb.beforeSend = (url, options) => {
|
this.pb.beforeSend = (url, options) => {
|
||||||
|
|||||||
@@ -23,15 +23,15 @@ export function useOptimisticMutation<TData, TVariables = unknown>(
|
|||||||
|
|
||||||
return { previousData };
|
return { previousData };
|
||||||
},
|
},
|
||||||
onError: (error, variables, context) => {
|
onError: (error, variables, onMutateResult, context) => {
|
||||||
if (context && typeof context === 'object' && 'previousData' in context && context.previousData) {
|
if (context && typeof context === 'object' && 'previousData' in context && context.previousData) {
|
||||||
queryClient.setQueryData(queryKey, context.previousData);
|
queryClient.setQueryData(queryKey, context.previousData);
|
||||||
}
|
}
|
||||||
mutationOptions.onError?.(error, variables, context);
|
mutationOptions.onError?.(error, variables, onMutateResult, context);
|
||||||
},
|
},
|
||||||
onSettled: (data, error, variables, context) => {
|
onSettled: (data, error, variables, onMutateResult, context) => {
|
||||||
queryClient.invalidateQueries({ queryKey });
|
queryClient.invalidateQueries({ queryKey });
|
||||||
mutationOptions.onSettled?.(data, error, variables, context);
|
mutationOptions.onSettled?.(data, error, variables, onMutateResult, context);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export function useServerMutation<TData, TVariables = unknown>(
|
|||||||
if (errorData?.error === "SESSION_REFRESH_REQUIRED") {
|
if (errorData?.error === "SESSION_REFRESH_REQUIRED") {
|
||||||
const currentUrl = window.location.pathname + window.location.search;
|
const currentUrl = window.location.pathname + window.location.search;
|
||||||
window.location.href = `/refresh-session?redirect=${encodeURIComponent(currentUrl)}`;
|
window.location.href = `/refresh-session?redirect=${encodeURIComponent(currentUrl)}`;
|
||||||
|
console.log('redirecting 2')
|
||||||
throw new Error("SESSION_REFRESH_REQUIRED");
|
throw new Error("SESSION_REFRESH_REQUIRED");
|
||||||
}
|
}
|
||||||
} catch (parseError) {}
|
} catch (parseError) {}
|
||||||
@@ -52,14 +53,14 @@ export function useServerMutation<TData, TVariables = unknown>(
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSuccess: (data, variables, context) => {
|
onSuccess: (data, variables, onMutateResult, context) => {
|
||||||
if (showSuccessToast && successMessage) {
|
if (showSuccessToast && successMessage) {
|
||||||
toast.success(successMessage);
|
toast.success(successMessage);
|
||||||
}
|
}
|
||||||
onSuccess?.(data, variables, context);
|
onSuccess?.(data, variables, onMutateResult, context);
|
||||||
},
|
},
|
||||||
onError: (error, variables, context) => {
|
onError: (error, variables, onMutateResult, context) => {
|
||||||
onError?.(error, variables, context);
|
onError?.(error, variables, onMutateResult, context);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ export const getSessionContext = async (request: Request, options?: { isServerFu
|
|||||||
|
|
||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
const from = encodeURIComponent(url.pathname + url.search);
|
const from = encodeURIComponent(url.pathname + url.search);
|
||||||
|
console.log('redirecting')
|
||||||
throw redirect({
|
throw redirect({
|
||||||
to: "/refresh-session",
|
to: "/refresh-session",
|
||||||
search: { redirect: from }
|
search: { redirect: from }
|
||||||
|
|||||||
@@ -18,5 +18,11 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
react()
|
react()
|
||||||
]
|
],
|
||||||
|
build: {
|
||||||
|
target: 'esnext',
|
||||||
|
},
|
||||||
|
ssr: {
|
||||||
|
target: 'node',
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user