team logo compression, play around with style
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
"@tiptap/starter-kit": "^3.4.3",
|
||||
"@types/bun": "^1.2.22",
|
||||
"@types/ioredis": "^4.28.10",
|
||||
"browser-image-compression": "^2.0.2",
|
||||
"dotenv": "^17.2.2",
|
||||
"embla-carousel-react": "^8.6.0",
|
||||
"framer-motion": "^12.23.12",
|
||||
|
||||
@@ -6,7 +6,10 @@ interface HeaderProps extends HeaderConfig {}
|
||||
|
||||
const Header = ({ collapsed, title, withBackButton }: HeaderProps) => {
|
||||
return (
|
||||
<AppShell.Header id='app-header' display={collapsed ? 'none' : 'block'}>
|
||||
<AppShell.Header
|
||||
id='app-header'
|
||||
display={collapsed ? 'none' : 'block'}
|
||||
>
|
||||
{ withBackButton && <BackButton /> }
|
||||
<Flex justify='center' align='center' h='100%' px='md'>
|
||||
<Title order={2}>{title}</Title>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AppShell, ScrollArea, Stack, Group, Paper } from "@mantine/core";
|
||||
import { AppShell, ScrollArea, Stack, Group, Paper, useMantineColorScheme } from "@mantine/core";
|
||||
import { Link } from "@tanstack/react-router";
|
||||
import { NavLink } from "./nav-link";
|
||||
import { useIsMobile } from "@/hooks/use-is-mobile";
|
||||
@@ -9,11 +9,17 @@ import { memo } from "react";
|
||||
const Navbar = () => {
|
||||
const { user, roles } = useAuth()
|
||||
const isMobile = useIsMobile();
|
||||
const { colorScheme } = useMantineColorScheme();
|
||||
|
||||
const links = useLinks(user?.id, roles);
|
||||
|
||||
const isDark = colorScheme === 'dark';
|
||||
const borderColor = isDark ? 'var(--mantine-color-dimmed)' : 'black';
|
||||
const boxShadowColor = isDark ? 'var(--mantine-color-dimmed)' : 'black';
|
||||
// boxShadow: `5px 5px ${boxShadowColor}`, borderColor
|
||||
|
||||
if (isMobile) return (
|
||||
<Paper component='nav' role='navigation' withBorder radius='lg' h='4rem' w='calc(100% - 1rem)' shadow='sm' pos='fixed' m='0.5rem' bottom='0' style={{ zIndex: 10 }}>
|
||||
<Paper component='nav' role='navigation' withBorder shadow="sm" radius='lg' h='4rem' w='calc(100% - 1.5rem)' pos='fixed' m='0.75rem' bottom='0' style={{ zIndex: 10 }}>
|
||||
<Group gap='xs' justify='space-around' h='100%' w='100%' px={{ base: 12, sm: 0 }}>
|
||||
{links.map((link) => (
|
||||
<NavLink key={link.href} {...link} />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Badge, FileInput, Group, Stack, Text, TextInput } from "@mantine/core";
|
||||
import { FileInput, Stack, TextInput } from "@mantine/core";
|
||||
import { useForm, UseFormInput } from "@mantine/form";
|
||||
import { LinkIcon } from "@phosphor-icons/react";
|
||||
import SlidePanel, { SlidePanelField } from "@/components/sheet/slide-panel";
|
||||
import SlidePanel from "@/components/sheet/slide-panel";
|
||||
import { isNotEmpty } from "@mantine/form";
|
||||
import useCreateTeam from "../../hooks/use-create-team";
|
||||
import useUpdateTeam from "../../hooks/use-update-team";
|
||||
@@ -13,8 +13,8 @@ import { useCallback } from "react";
|
||||
import { TeamInput } from "../../types";
|
||||
import { teamKeys } from "../../queries";
|
||||
import SongPicker from "./song-picker";
|
||||
import TeamColorPicker from "./color-picker";
|
||||
import PlayersPicker from "./players-picker";
|
||||
import imageCompression from "browser-image-compression";
|
||||
|
||||
interface TeamFormProps {
|
||||
close: () => void;
|
||||
@@ -113,9 +113,32 @@ const TeamForm = ({
|
||||
|
||||
if (logo && team) {
|
||||
try {
|
||||
let processedLogo = logo;
|
||||
|
||||
if (logo.size > 500 * 1024) {
|
||||
const compressionOptions = {
|
||||
maxSizeMB: 0.5,
|
||||
maxWidthOrHeight: 800,
|
||||
useWebWorker: true,
|
||||
fileType: logo.type,
|
||||
};
|
||||
|
||||
try {
|
||||
processedLogo = await imageCompression(logo, compressionOptions);
|
||||
logger.info("image compressed", {
|
||||
originalSize: logo.size,
|
||||
compressedSize: processedLogo.size,
|
||||
reduction: ((logo.size - processedLogo.size) / logo.size * 100).toFixed(1) + "%"
|
||||
});
|
||||
} catch (compressionError) {
|
||||
logger.warn("compression failed, falling back", compressionError);
|
||||
processedLogo = logo;
|
||||
}
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("teamId", team.id);
|
||||
formData.append("logo", logo);
|
||||
formData.append("logo", processedLogo);
|
||||
|
||||
const response = await fetch("/api/teams/upload-logo", {
|
||||
method: "POST",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { PKCEState, SpotifyTokenResponse } from './types';
|
||||
import type { SpotifyTokenResponse } from './types';
|
||||
|
||||
const SPOTIFY_AUTH_BASE = 'https://accounts.spotify.com';
|
||||
const SPOTIFY_SCOPES = [
|
||||
|
||||
Reference in New Issue
Block a user