IntegrationWindowLayout.tsx97 lines · main
1import { Book, LifeBuoy, X } from 'lucide-react'
2import Link from 'next/link'
3import { forwardRef, PropsWithChildren, ReactNode } from 'react'
4import { cn, LoadingLine } from 'ui'
5
6import { ScaffoldContainer } from '../Scaffold'
7import { withAuth } from '@/hooks/misc/withAuth'
8import { BASE_PATH } from '@/lib/constants'
9
10export type IntegrationWindowLayoutProps = {
11 title: string
12 integrationIcon: ReactNode
13 loading?: boolean
14 docsHref?: string
15}
16
17const IntegrationWindowLayout = ({
18 title,
19 integrationIcon,
20 children,
21 loading = false,
22 docsHref,
23}: PropsWithChildren<IntegrationWindowLayoutProps>) => {
24 return (
25 <div className="flex w-full flex-col">
26 <Header title={title} integrationIcon={integrationIcon} />
27 <LoadingLine loading={loading} />
28 <main className="overflow-auto flex flex-col h-full bg">{children}</main>
29 <ScaffoldContainer className="bg-studio flex flex-row gap-6 py-6 border-t">
30 {docsHref && (
31 <Link
32 href={docsHref}
33 target="_blank"
34 rel="noopener noreferrer"
35 className="flex items-center gap-2 text-xs text-foreground-light hover:text"
36 >
37 <Book size={16} />
38 Docs
39 </Link>
40 )}
41 <Link
42 href={'https://supabase.com/support'}
43 target="_blank"
44 rel="noopener noreferrer"
45 className="flex items-center gap-2 text-xs text-light hover:text"
46 >
47 <LifeBuoy size={16} />
48 Support
49 </Link>
50 </ScaffoldContainer>
51 </div>
52 )
53}
54
55const INTEGRATION_LAYOUT_MAX_WIDTH = '' // 'max-w-[720px]'
56
57export default withAuth(IntegrationWindowLayout)
58
59export const IntegrationWindowLayoutWithoutAuth = IntegrationWindowLayout
60
61export type HeaderProps = {
62 title: string
63 integrationIcon: ReactNode
64}
65
66const Header = ({ title, integrationIcon }: HeaderProps) => {
67 return (
68 <div className="bg">
69 <ScaffoldContainer className={cn('py-3', INTEGRATION_LAYOUT_MAX_WIDTH)}>
70 <div className="flex items-center gap-6 w-full">
71 <div className="flex gap-2 items-center">
72 <div className="bg-white shadow-sm border rounded-sm p-1 w-8 h-8 flex justify-center items-center">
73 <img src={`${BASE_PATH}/img/briven-logo.svg`} alt="Briven" className="w-4" />
74 </div>
75 <X className="text-border-stronger" strokeWidth={2} size={16} />
76 {integrationIcon}
77 </div>
78 <span className="text-sm" title={title}>
79 {title}
80 </span>
81 </div>
82 </ScaffoldContainer>
83 </div>
84 )
85}
86
87const maxWidthClasses = 'mx-auto w-full max-w-[1600px]'
88const paddingClasses = 'px-6 lg:px-14 xl:px-28 2xl:px-32'
89
90export const IntegrationScaffoldContainer = forwardRef<
91 HTMLDivElement,
92 React.HTMLAttributes<HTMLDivElement>
93>(({ className, ...props }, ref) => {
94 return <div ref={ref} {...props} className={cn(maxWidthClasses, paddingClasses, className)} />
95})
96
97IntegrationScaffoldContainer.displayName = 'IntegrationScaffoldContainer'