fix: address PR feedback (SVG helper & AddOrganization crash)

This commit is contained in:
Yash Kumar
2026-09-02 20:49:14 +05:30
parent f617561d0b
commit 4877c4ffa3
3 changed files with 25 additions and 27 deletions
@@ -1,4 +1,3 @@
import DOMPurify from "dompurify";
import { CircuitBoard, GlobeIcon, Pencil, Search, X } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
@@ -14,6 +13,7 @@ import { Dropzone } from "@/components/ui/dropzone";
import { Input } from "@/components/ui/input";
import { type BundledIcon, bundledIcons } from "@/lib/bundled-icons";
import { api } from "@/utils/api";
import { sanitizeSvg } from "@/utils/sanitize-svg";
interface ShowIconSettingsProps {
serviceId: string;
@@ -89,15 +89,6 @@ export const ShowIconSettings = ({
}
};
const sanitizeSvg = (svgContent: string): string | null => {
const clean = DOMPurify.sanitize(svgContent, {
USE_PROFILES: { svg: true, svgFilters: true },
ADD_TAGS: ["use"],
});
if (!clean) return null;
return `data:image/svg+xml;base64,${btoa(clean)}`;
};
const handleFileUpload = async (files: FileList | null) => {
if (!files || files.length === 0) return;
const file = files[0];
@@ -1,7 +1,7 @@
import { standardSchemaResolver as zodResolver } from "@hookform/resolvers/standard-schema";
import DOMPurify from "dompurify";
import { GlobeIcon, PenBoxIcon, Plus, X } from "lucide-react";
import { useEffect, useState, useRef } from "react";
import { useEffect, useRef, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
@@ -26,6 +26,7 @@ import {
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { sanitizeSvg } from "@/utils/sanitize-svg";
const organizationSchema = z.object({
name: z.string().min(1, {
@@ -43,20 +44,6 @@ interface Props {
onOpenChange?: (open: boolean) => void;
}
const sanitizeSvg = (svgContent: string): string | null => {
const clean = DOMPurify.sanitize(svgContent, {
USE_PROFILES: { svg: true, svgFilters: true },
ADD_TAGS: ["use"],
});
if (!clean) return null;
const bytes = new TextEncoder().encode(clean);
let binString = "";
for (let i = 0; i < bytes.length; i++) {
binString += String.fromCharCode(bytes[i]!);
}
return `data:image/svg+xml;base64,${btoa(binString)}`;
};
const resizeImage = (file: File, maxSize: number): Promise<string> => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
@@ -106,7 +93,9 @@ export function AddOrganization({
const uploadCounter = useRef(0);
const isControlled = controlledOpen !== undefined;
const open = isControlled ? controlledOpen : internalOpen;
const setOpen = isControlled ? controlledOnOpenChange! : setInternalOpen;
const setOpen = isControlled
? controlledOnOpenChange || (() => {})
: setInternalOpen;
const utils = api.useUtils();
const { data: organization } = api.organization.one.useQuery(
{
+18
View File
@@ -0,0 +1,18 @@
import DOMPurify from "dompurify";
export const sanitizeSvg = (svgContent: string): string | null => {
const clean = DOMPurify.sanitize(svgContent, {
USE_PROFILES: { svg: true, svgFilters: true },
});
if (!clean) return null;
// Fix unicode base64 bug (TextEncoder byte-loop handles non-Latin1 chars)
const bytes = new TextEncoder().encode(clean);
let binString = "";
for (let i = 0; i < bytes.length; i++) {
binString += String.fromCharCode(bytes[i]!);
}
return `data:image/svg+xml;base64,${btoa(binString)}`;
};