|
| 1 | +import React from 'react'; |
| 2 | +import clsx from 'clsx'; |
| 3 | +import Link from 'next/link'; |
| 4 | +import { OrbitIcon } from 'lucide-react'; |
| 5 | +import { GlowBg } from '@/components/shared/ui/glow-bg'; |
| 6 | + |
| 7 | +/** |
| 8 | + * A footer component meant to be used in the landing page. |
| 9 | + * It shows a footer with a title, description, and can render columns of links etc. |
| 10 | + */ |
| 11 | +export const LandingFooter = ({ |
| 12 | + className, |
| 13 | + children, |
| 14 | + title, |
| 15 | + description, |
| 16 | + footnote, |
| 17 | + logoComponent, |
| 18 | + withBackground = false, |
| 19 | + withBackgroundGlow = false, |
| 20 | + variant = 'primary', |
| 21 | + backgroundGlowVariant = 'primary', |
| 22 | +}: { |
| 23 | + className?: string; |
| 24 | + children?: React.ReactNode; |
| 25 | + title?: string; |
| 26 | + description?: string; |
| 27 | + footnote?: string | React.ReactNode; |
| 28 | + logoComponent?: React.ReactNode; |
| 29 | + withBackground?: boolean; |
| 30 | + withBackgroundGlow?: boolean; |
| 31 | + variant?: 'primary' | 'secondary'; |
| 32 | + backgroundGlowVariant?: 'primary' | 'secondary'; |
| 33 | +}) => { |
| 34 | + const columnNumber = React.Children.count(children); |
| 35 | + |
| 36 | + return ( |
| 37 | + <footer |
| 38 | + className={clsx( |
| 39 | + 'mt-auto w-full bg-gradient-to-r from-white/5 via-white/60 to-white/5 backdrop-blur-sm dark:from-slate-700/5 dark:via-slate-700/60 dark:to-slate-700/5', |
| 40 | + withBackground && variant === 'primary' |
| 41 | + ? 'bg-primary-100/20 dark:bg-primary-900/10' |
| 42 | + : '', |
| 43 | + withBackground && variant === 'secondary' |
| 44 | + ? 'bg-secondary-100/20 dark:bg-secondary-900/10' |
| 45 | + : '', |
| 46 | + withBackgroundGlow ? 'relative overflow-hidden' : '', |
| 47 | + className, |
| 48 | + )} |
| 49 | + > |
| 50 | + {withBackgroundGlow ? ( |
| 51 | + <div className="hidden lg:flex justify-center w-full h-full absolute -bottom-1/2 pointer-events-none"> |
| 52 | + <GlowBg |
| 53 | + className={clsx('w-full h-auto z-0 dark:opacity-50 opacity-100')} |
| 54 | + variant={backgroundGlowVariant} |
| 55 | + /> |
| 56 | + </div> |
| 57 | + ) : null} |
| 58 | + |
| 59 | + <div |
| 60 | + className={clsx( |
| 61 | + 'flex flex-col gap-4 justify-between items-center w-full p-6', |
| 62 | + )} |
| 63 | + > |
| 64 | + <div className="w-full flex flex-col md:flex-row justify-between gap-6 mt-12 p-6 max-w-full container-wide"> |
| 65 | + <div className="w-full flex flex-col gap-4 md:max-w-xs lg:max-w-sm"> |
| 66 | + <Link href="/"> |
| 67 | + {logoComponent || ( |
| 68 | + <div className="flex items-center gap-3 justify-start"> |
| 69 | + <OrbitIcon className="h-8 w-8 text-primary-900 dark:text-primary-100" /> |
| 70 | + |
| 71 | + <div className="hidden text-2xl font-semibold font-display sm:flex gap-2 h-full"> |
| 72 | + Page <span className="font-bold">UI</span> |
| 73 | + </div> |
| 74 | + </div> |
| 75 | + )} |
| 76 | + </Link> |
| 77 | + |
| 78 | + {title ? ( |
| 79 | + <div className="text-lg font-semibold h-full">{title}</div> |
| 80 | + ) : null} |
| 81 | + |
| 82 | + {description ? ( |
| 83 | + <p className="text-sm opacity-70">{description}</p> |
| 84 | + ) : null} |
| 85 | + </div> |
| 86 | + |
| 87 | + <div |
| 88 | + className={clsx( |
| 89 | + 'grid md:grid-cols-2 gap-12 items-start mt-6 md:mt-0', |
| 90 | + columnNumber === 3 ? 'md:grid-cols-3' : '', |
| 91 | + columnNumber === 4 ? 'lg:grid-cols-4' : '', |
| 92 | + )} |
| 93 | + > |
| 94 | + {children} |
| 95 | + </div> |
| 96 | + </div> |
| 97 | + </div> |
| 98 | + |
| 99 | + {footnote ? ( |
| 100 | + <div> |
| 101 | + <hr |
| 102 | + className="w-full my-4 border-0 bg-gradient-to-r from-white/5 via-black/10 to-white/5 dark:from-black/5 dark:via-white/30 darK:to-black/5" |
| 103 | + style={{ height: '1px' }} |
| 104 | + /> |
| 105 | + |
| 106 | + <div className="py-8 px-2 flex flex-col items-center"> |
| 107 | + <div className="w-full text-center lg:flex lg:justify-center p-4 mb-2 space-x-2 text-sm text-gray-500 dark:text-gray-400"> |
| 108 | + {footnote} |
| 109 | + </div> |
| 110 | + </div> |
| 111 | + </div> |
| 112 | + ) : null} |
| 113 | + </footer> |
| 114 | + ); |
| 115 | +}; |
0 commit comments