Please upload a logo
{!hasLoadedPreview && (
-
@@ -243,7 +243,7 @@ export function BrandingPreferencesForm({
type="button"
variant="link"
size="sm"
- className="text-destructive text-xs"
+ className="text-xs text-destructive"
onClick={() => {
setPreviewUrl('');
onChange(null);
diff --git a/apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.branding.tsx b/apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.branding.tsx
index 64f8511ed..8f5e47117 100644
--- a/apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.branding.tsx
+++ b/apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.branding.tsx
@@ -48,12 +48,17 @@ export default function OrganisationSettingsBrandingPage() {
try {
const { brandingEnabled, brandingLogo, brandingUrl, brandingCompanyDetails } = data;
- let uploadedBrandingLogo: string | undefined = '';
+ let uploadedBrandingLogo: string | undefined = undefined;
if (brandingLogo) {
uploadedBrandingLogo = JSON.stringify(await putFile(brandingLogo));
}
+ // Empty the branding logo if the user unsets it.
+ if (brandingLogo === null) {
+ uploadedBrandingLogo = '';
+ }
+
await updateOrganisationSettings({
organisationId: organisation.id,
data: {
diff --git a/apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.branding.tsx b/apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.branding.tsx
index a7317505f..9ffc05255 100644
--- a/apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.branding.tsx
+++ b/apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.branding.tsx
@@ -34,12 +34,13 @@ export default function TeamsSettingsPage() {
try {
const { brandingEnabled, brandingLogo, brandingUrl, brandingCompanyDetails } = data;
- let uploadedBrandingLogo = teamWithSettings?.teamSettings?.brandingLogo;
+ let uploadedBrandingLogo: string | undefined = undefined;
if (brandingLogo) {
uploadedBrandingLogo = JSON.stringify(await putFile(brandingLogo));
}
+ // Empty the branding logo if the user unsets it.
if (brandingLogo === null) {
uploadedBrandingLogo = '';
}
@@ -48,7 +49,7 @@ export default function TeamsSettingsPage() {
teamId: team.id,
data: {
brandingEnabled,
- brandingLogo: uploadedBrandingLogo || null,
+ brandingLogo: uploadedBrandingLogo,
brandingUrl: brandingUrl || null,
brandingCompanyDetails: brandingCompanyDetails || null,
},
diff --git a/apps/remix/app/routes/api+/branding.logo.organisation.$orgId.ts b/apps/remix/app/routes/api+/branding.logo.organisation.$orgId.ts
index da6c8da1a..050bb4a6b 100644
--- a/apps/remix/app/routes/api+/branding.logo.organisation.$orgId.ts
+++ b/apps/remix/app/routes/api+/branding.logo.organisation.$orgId.ts
@@ -1,10 +1,13 @@
+import { sha256 } from '@documenso/lib/universal/crypto';
import { getFileServerSide } from '@documenso/lib/universal/upload/get-file.server';
import { loadLogo } from '@documenso/lib/utils/images/logo';
import { prisma } from '@documenso/prisma';
import type { Route } from './+types/branding.logo.organisation.$orgId';
-export async function loader({ params }: Route.LoaderArgs) {
+const CACHE_CONTROL = 'public, max-age=0, stale-while-revalidate=86400';
+
+export async function loader({ params, request }: Route.LoaderArgs) {
const organisationId = params.orgId;
if (!organisationId) {
@@ -48,6 +51,18 @@ export async function loader({ params }: Route.LoaderArgs) {
);
}
+ const etag = `"${Buffer.from(sha256(settings.brandingLogo)).toString('hex')}"`;
+
+ if (request.headers.get('If-None-Match') === etag) {
+ return new Response(null, {
+ status: 304,
+ headers: {
+ ETag: etag,
+ 'Cache-Control': CACHE_CONTROL,
+ },
+ });
+ }
+
const file = await getFileServerSide(JSON.parse(settings.brandingLogo)).catch((e) => {
console.error(e);
});
@@ -68,8 +83,8 @@ export async function loader({ params }: Route.LoaderArgs) {
headers: {
'Content-Type': contentType,
'Content-Length': content.length.toString(),
- // Stale while revalidate for 1 hours to 24 hours
- 'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400',
+ 'Cache-Control': CACHE_CONTROL,
+ ETag: etag,
},
});
}
diff --git a/apps/remix/app/routes/api+/branding.logo.team.$teamId.ts b/apps/remix/app/routes/api+/branding.logo.team.$teamId.ts
index 30a0e5b3c..923e8e0ca 100644
--- a/apps/remix/app/routes/api+/branding.logo.team.$teamId.ts
+++ b/apps/remix/app/routes/api+/branding.logo.team.$teamId.ts
@@ -1,10 +1,13 @@
import { getTeamSettings } from '@documenso/lib/server-only/team/get-team-settings';
+import { sha256 } from '@documenso/lib/universal/crypto';
import { getFileServerSide } from '@documenso/lib/universal/upload/get-file.server';
import { loadLogo } from '@documenso/lib/utils/images/logo';
import type { Route } from './+types/branding.logo.team.$teamId';
-export async function loader({ params }: Route.LoaderArgs) {
+const CACHE_CONTROL = 'public, max-age=0, stale-while-revalidate=86400';
+
+export async function loader({ params, request }: Route.LoaderArgs) {
const teamId = Number(params.teamId);
if (teamId === 0 || Number.isNaN(teamId)) {
@@ -41,6 +44,18 @@ export async function loader({ params }: Route.LoaderArgs) {
);
}
+ const etag = `"${Buffer.from(sha256(settings.brandingLogo)).toString('hex')}"`;
+
+ if (request.headers.get('If-None-Match') === etag) {
+ return new Response(null, {
+ status: 304,
+ headers: {
+ ETag: etag,
+ 'Cache-Control': CACHE_CONTROL,
+ },
+ });
+ }
+
const file = await getFileServerSide(JSON.parse(settings.brandingLogo)).catch((e) => {
console.error(e);
});
@@ -61,8 +76,8 @@ export async function loader({ params }: Route.LoaderArgs) {
headers: {
'Content-Type': contentType,
'Content-Length': content.length.toString(),
- // Stale while revalidate for 1 hours to 24 hours
- 'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400',
+ 'Cache-Control': CACHE_CONTROL,
+ ETag: etag,
},
});
}