Merge branch 'main' into feat/building-documenso-part-2
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
"@documenso/trpc": "*",
|
"@documenso/trpc": "*",
|
||||||
"@documenso/ui": "*",
|
"@documenso/ui": "*",
|
||||||
"@hookform/resolvers": "^3.1.0",
|
"@hookform/resolvers": "^3.1.0",
|
||||||
|
"@openstatus/react": "^0.0.3",
|
||||||
"contentlayer": "^0.3.4",
|
"contentlayer": "^0.3.4",
|
||||||
"framer-motion": "^10.12.8",
|
"framer-motion": "^10.12.8",
|
||||||
"lucide-react": "^0.279.0",
|
"lucide-react": "^0.279.0",
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import LogoImage from '@documenso/assets/logo.png';
|
|||||||
import { cn } from '@documenso/ui/lib/utils';
|
import { cn } from '@documenso/ui/lib/utils';
|
||||||
import { ThemeSwitcher } from '@documenso/ui/primitives/theme-switcher';
|
import { ThemeSwitcher } from '@documenso/ui/primitives/theme-switcher';
|
||||||
|
|
||||||
|
import { StatusWidgetContainer } from './status-widget-container';
|
||||||
|
|
||||||
export type FooterProps = HTMLAttributes<HTMLDivElement>;
|
export type FooterProps = HTMLAttributes<HTMLDivElement>;
|
||||||
|
|
||||||
const SOCIAL_LINKS = [
|
const SOCIAL_LINKS = [
|
||||||
@@ -62,6 +64,10 @@ export const Footer = ({ className, ...props }: FooterProps) => {
|
|||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-6">
|
||||||
|
<StatusWidgetContainer />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid w-full max-w-sm grid-cols-2 gap-x-4 gap-y-2 md:w-auto md:gap-x-8">
|
<div className="grid w-full max-w-sm grid-cols-2 gap-x-4 gap-y-2 md:w-auto md:gap-x-8">
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// https://github.com/documenso/documenso/pull/1044/files#r1538258462
|
||||||
|
import { Suspense } from 'react';
|
||||||
|
|
||||||
|
import { StatusWidget } from './status-widget';
|
||||||
|
|
||||||
|
export function StatusWidgetContainer() {
|
||||||
|
return (
|
||||||
|
<Suspense fallback={<StatusWidgetFallback />}>
|
||||||
|
<StatusWidget />
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function StatusWidgetFallback() {
|
||||||
|
return (
|
||||||
|
<div className="border-border inline-flex max-w-fit items-center justify-between space-x-2 rounded-md border border-gray-200 px-2 py-2 pr-3 text-sm">
|
||||||
|
<span className="bg-muted h-2 w-36 animate-pulse rounded-md" />
|
||||||
|
<span className="bg-muted relative inline-flex h-2 w-2 rounded-full" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
75
apps/marketing/src/components/(marketing)/status-widget.tsx
Normal file
75
apps/marketing/src/components/(marketing)/status-widget.tsx
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import { use, useMemo } from 'react';
|
||||||
|
|
||||||
|
import type { Status } from '@openstatus/react';
|
||||||
|
import { getStatus } from '@openstatus/react';
|
||||||
|
|
||||||
|
import { cn } from '@documenso/ui/lib/utils';
|
||||||
|
|
||||||
|
const getStatusLevel = (level: Status) => {
|
||||||
|
return {
|
||||||
|
operational: {
|
||||||
|
label: 'Operational',
|
||||||
|
color: 'bg-green-500',
|
||||||
|
color2: 'bg-green-400',
|
||||||
|
},
|
||||||
|
degraded_performance: {
|
||||||
|
label: 'Degraded Performance',
|
||||||
|
color: 'bg-yellow-500',
|
||||||
|
color2: 'bg-yellow-400',
|
||||||
|
},
|
||||||
|
partial_outage: {
|
||||||
|
label: 'Partial Outage',
|
||||||
|
color: 'bg-yellow-500',
|
||||||
|
color2: 'bg-yellow-400',
|
||||||
|
},
|
||||||
|
major_outage: {
|
||||||
|
label: 'Major Outage',
|
||||||
|
color: 'bg-red-500',
|
||||||
|
color2: 'bg-red-400',
|
||||||
|
},
|
||||||
|
unknown: {
|
||||||
|
label: 'Unknown',
|
||||||
|
color: 'bg-gray-500',
|
||||||
|
color2: 'bg-gray-400',
|
||||||
|
},
|
||||||
|
incident: {
|
||||||
|
label: 'Incident',
|
||||||
|
color: 'bg-yellow-500',
|
||||||
|
color2: 'bg-yellow-400',
|
||||||
|
},
|
||||||
|
under_maintenance: {
|
||||||
|
label: 'Under Maintenance',
|
||||||
|
color: 'bg-gray-500',
|
||||||
|
color2: 'bg-gray-400',
|
||||||
|
},
|
||||||
|
}[level];
|
||||||
|
};
|
||||||
|
|
||||||
|
export function StatusWidget() {
|
||||||
|
const getStatusMemoized = useMemo(async () => getStatus('documenso-status'), []);
|
||||||
|
const { status } = use(getStatusMemoized);
|
||||||
|
const level = getStatusLevel(status);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
className="border-border inline-flex max-w-fit items-center justify-between gap-2 space-x-2 rounded-md border border-gray-200 px-3 py-1 text-sm"
|
||||||
|
href="https://status.documenso.com"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<p className="text-sm">{level.label}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className="relative ml-auto flex h-1.5 w-1.5">
|
||||||
|
<span
|
||||||
|
className={cn(
|
||||||
|
'absolute inline-flex h-full w-full animate-ping rounded-full opacity-75',
|
||||||
|
level.color2,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<span className={cn('relative inline-flex h-1.5 w-1.5 rounded-full', level.color)} />
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
9
package-lock.json
generated
9
package-lock.json
generated
@@ -42,6 +42,7 @@
|
|||||||
"@documenso/trpc": "*",
|
"@documenso/trpc": "*",
|
||||||
"@documenso/ui": "*",
|
"@documenso/ui": "*",
|
||||||
"@hookform/resolvers": "^3.1.0",
|
"@hookform/resolvers": "^3.1.0",
|
||||||
|
"@openstatus/react": "^0.0.3",
|
||||||
"contentlayer": "^0.3.4",
|
"contentlayer": "^0.3.4",
|
||||||
"framer-motion": "^10.12.8",
|
"framer-motion": "^10.12.8",
|
||||||
"lucide-react": "^0.279.0",
|
"lucide-react": "^0.279.0",
|
||||||
@@ -4142,6 +4143,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
|
||||||
"integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw=="
|
"integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@openstatus/react": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@openstatus/react/-/react-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-uDiegz7e3H67pG8lTT+op+6w5keTT7XpcENrREaqlWl5j53TYyO8nheOG1PeNw2/Qgd5KaGeRJJFn1crhTUSYw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@opentelemetry/api": {
|
"node_modules/@opentelemetry/api": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz",
|
||||||
|
|||||||
Reference in New Issue
Block a user