@ardly/bunext 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +33 -16
- package/cli.mjs +126 -0
- package/package.json +14 -58
- package/.eslintrc.json +0 -8
- package/.prettierignore +0 -4
- package/STRUCTURE.md +0 -77
- package/bin/cli.mjs +0 -126
- package/components.json +0 -21
- package/next.config.ts +0 -22
- package/postcss.config.mjs +0 -8
- package/prettier.config.js +0 -7
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/favicon.svg +0 -1
- package/public/loading-dots.gif +0 -0
- package/public/logo.svg +0 -1
- package/public/ogImage.webp +0 -0
- package/public/site.webmanifest +0 -19
- package/src/actions/placeholder.ts +0 -30
- package/src/actions/sampleAction.ts +0 -39
- package/src/app/(index)/intr/TestCard.tsx +0 -31
- package/src/app/(index)/intr/page.tsx +0 -17
- package/src/app/(index)/page.tsx +0 -156
- package/src/app/(index)/pagetr/page.tsx +0 -37
- package/src/app/error-wrapper.tsx +0 -32
- package/src/app/global-error.tsx +0 -53
- package/src/app/layout.tsx +0 -56
- package/src/app/loading.tsx +0 -11
- package/src/app/not-found.tsx +0 -45
- package/src/app/sitemap.ts +0 -14
- package/src/components/Providers/root-provider.tsx +0 -22
- package/src/components/Providers/theme-provider.tsx +0 -27
- package/src/components/TestComp.tsx +0 -11
- package/src/components/brand.tsx +0 -35
- package/src/components/navigation/footer.tsx +0 -32
- package/src/components/navigation/main-nav.tsx +0 -55
- package/src/components/navigation/mobile-nav.tsx +0 -154
- package/src/components/navigation/site-header.tsx +0 -67
- package/src/components/ui/avatar.tsx +0 -50
- package/src/components/ui/badge.tsx +0 -36
- package/src/components/ui/button.tsx +0 -56
- package/src/components/ui/card.tsx +0 -79
- package/src/components/ui/command.tsx +0 -153
- package/src/components/ui/dialog.tsx +0 -122
- package/src/components/ui/drawer.tsx +0 -118
- package/src/components/ui/dropdown-menu.tsx +0 -200
- package/src/components/ui/input.tsx +0 -22
- package/src/components/ui/label.tsx +0 -26
- package/src/components/ui/multi-select.tsx +0 -380
- package/src/components/ui/origin/multiselect.tsx +0 -645
- package/src/components/ui/popover.tsx +0 -31
- package/src/components/ui/radio-group.tsx +0 -44
- package/src/components/ui/separator.tsx +0 -31
- package/src/components/ui/skeleton.tsx +0 -15
- package/src/components/ui/themeSelector.tsx +0 -157
- package/src/components/ui/toast.tsx +0 -129
- package/src/components/ui/toaster.tsx +0 -31
- package/src/components/ui/tooltip.tsx +0 -39
- package/src/components/utils/ConditionalLink.tsx +0 -46
- package/src/components/utils/Image.tsx +0 -57
- package/src/components/utils/Img.tsx +0 -104
- package/src/components/utils/Spinner.tsx +0 -29
- package/src/components/utils/TopButton.tsx +0 -67
- package/src/components/utils/TransitionLink.tsx +0 -67
- package/src/components/utils/copy.tsx +0 -98
- package/src/components/utils/featureFlag.tsx +0 -22
- package/src/components/utils/icons.tsx +0 -155
- package/src/components/utils/share-modal.tsx +0 -159
- package/src/hooks/use-intersection.ts +0 -52
- package/src/hooks/use-lazy-load.ts +0 -33
- package/src/hooks/use-meta-color.ts +0 -25
- package/src/hooks/use-toast.ts +0 -191
- package/src/lib/config/featureflags.ts +0 -63
- package/src/lib/config/siteConfig.ts +0 -172
- package/src/lib/config/user.ts +0 -9
- package/src/lib/data/footer-data.ts +0 -85
- package/src/lib/data/nav-data.ts +0 -30
- package/src/lib/data/siteData.ts +0 -52
- package/src/lib/utils/index.ts +0 -190
- package/src/styles/customGlobal.css +0 -141
- package/src/styles/globals.css +0 -72
- package/src/styles/tailwind/base.ts +0 -46
- package/src/styles/tailwind/fonts/ClashDisplay-Bold.eot +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Bold.ttf +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Bold.woff +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Bold.woff2 +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Extralight.eot +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Extralight.ttf +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Extralight.woff +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Extralight.woff2 +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Light.eot +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Light.ttf +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Light.woff +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Light.woff2 +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Medium.eot +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Medium.ttf +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Medium.woff +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Medium.woff2 +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Regular.eot +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Regular.ttf +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Regular.woff +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Regular.woff2 +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Semibold.eot +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Semibold.ttf +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Semibold.woff +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Semibold.woff2 +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Variable.eot +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Variable.ttf +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Variable.woff +0 -0
- package/src/styles/tailwind/fonts/ClashDisplay-Variable.woff2 +0 -0
- package/src/styles/tailwind/fonts/GeistMonoVF.woff +0 -0
- package/src/styles/tailwind/fonts/GeistVF.woff +0 -0
- package/src/styles/tailwind/fonts.ts +0 -51
- package/src/styles/tailwind/tailwindUtils.ts +0 -29
- package/src/types/index.ts +0 -80
- package/tailwind.config.ts +0 -104
- package/tsconfig.json +0 -28
- package/vercel.json +0 -6
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
// a btn to take user to the top of the page
|
|
3
|
-
import { useState, useEffect } from 'react'
|
|
4
|
-
import { ArrowUp } from 'lucide-react'
|
|
5
|
-
import { cn } from '@/lib/utils'
|
|
6
|
-
import {
|
|
7
|
-
Tooltip,
|
|
8
|
-
TooltipContent,
|
|
9
|
-
TooltipProvider,
|
|
10
|
-
TooltipTrigger,
|
|
11
|
-
} from '@/components/ui/tooltip'
|
|
12
|
-
|
|
13
|
-
export function ScrollToTopButton({
|
|
14
|
-
className,
|
|
15
|
-
iconClassName,
|
|
16
|
-
}: {
|
|
17
|
-
className?: string
|
|
18
|
-
iconClassName?: string
|
|
19
|
-
}) {
|
|
20
|
-
const [isVisible, setIsVisible] = useState(false)
|
|
21
|
-
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
const toggleVisibility = () => {
|
|
24
|
-
// Check if page is scrolled at all
|
|
25
|
-
if (window.scrollY > 0) setIsVisible(true)
|
|
26
|
-
else setIsVisible(false)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Check visibility on mount
|
|
30
|
-
toggleVisibility()
|
|
31
|
-
|
|
32
|
-
window.addEventListener('scroll', toggleVisibility)
|
|
33
|
-
return () => window.removeEventListener('scroll', toggleVisibility)
|
|
34
|
-
}, [])
|
|
35
|
-
|
|
36
|
-
const scrollToTop = () => {
|
|
37
|
-
window.scrollTo({
|
|
38
|
-
top: 0,
|
|
39
|
-
behavior: 'smooth',
|
|
40
|
-
})
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return (
|
|
44
|
-
<TooltipProvider>
|
|
45
|
-
<Tooltip>
|
|
46
|
-
<TooltipTrigger asChild>
|
|
47
|
-
<button
|
|
48
|
-
onClick={scrollToTop}
|
|
49
|
-
className={cn(
|
|
50
|
-
'rounded-xl bg-primary p-2 text-primary-foreground shadow-lg transition-all duration-300 hover:-translate-y-1 hover:bg-primary/90 hover:shadow-xl',
|
|
51
|
-
isVisible
|
|
52
|
-
? 'motion-scale-in-[0.24] motion-translate-x-in-[0%] motion-translate-y-in-[111%]'
|
|
53
|
-
: 'pointer-events-none motion-scale-out-[0] motion-translate-y-out-[90%] motion-opacity-out-[0%]',
|
|
54
|
-
className
|
|
55
|
-
)}
|
|
56
|
-
aria-label="Scroll to top"
|
|
57
|
-
>
|
|
58
|
-
<ArrowUp className={cn('size-4', iconClassName)} />
|
|
59
|
-
</button>
|
|
60
|
-
</TooltipTrigger>
|
|
61
|
-
<TooltipContent className="text-[12px]">
|
|
62
|
-
<p>Go to top</p>
|
|
63
|
-
</TooltipContent>
|
|
64
|
-
</Tooltip>
|
|
65
|
-
</TooltipProvider>
|
|
66
|
-
)
|
|
67
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
// per link page transition
|
|
3
|
-
import Link, { type LinkProps } from 'next/link'
|
|
4
|
-
import { useRouter } from 'next/navigation'
|
|
5
|
-
import type React from 'react'
|
|
6
|
-
|
|
7
|
-
import { sleep } from '@/lib/utils'
|
|
8
|
-
|
|
9
|
-
interface TransitionLinkProps extends LinkProps {
|
|
10
|
-
children: React.ReactNode
|
|
11
|
-
className?: string
|
|
12
|
-
href: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const transitionDuration = 300
|
|
16
|
-
// make sure to change the transition duration in customGlobal.css
|
|
17
|
-
export const PageTransition = async (
|
|
18
|
-
e: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
|
|
19
|
-
router: ReturnType<typeof useRouter>,
|
|
20
|
-
href: string
|
|
21
|
-
) => {
|
|
22
|
-
e.preventDefault()
|
|
23
|
-
const body = document.querySelector('body')
|
|
24
|
-
const prefersReducedMotion = window.matchMedia(
|
|
25
|
-
'(prefers-reduced-motion: reduce)'
|
|
26
|
-
).matches
|
|
27
|
-
|
|
28
|
-
// if user prefers reduced motion, then no transition
|
|
29
|
-
if (prefersReducedMotion) {
|
|
30
|
-
router.push(href)
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
body?.classList.add('page-transition')
|
|
35
|
-
|
|
36
|
-
await sleep(transitionDuration / 2 + 35)
|
|
37
|
-
router.push(href)
|
|
38
|
-
await sleep(transitionDuration / 2 + 35)
|
|
39
|
-
|
|
40
|
-
body?.classList.remove('page-transition')
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// TransitionLink component
|
|
44
|
-
export const TransitionLink: React.FC<TransitionLinkProps> = ({
|
|
45
|
-
children,
|
|
46
|
-
href,
|
|
47
|
-
className,
|
|
48
|
-
...props
|
|
49
|
-
}) => {
|
|
50
|
-
const router = useRouter()
|
|
51
|
-
|
|
52
|
-
const handleTransitionLocal = (
|
|
53
|
-
e: React.MouseEvent<HTMLAnchorElement, MouseEvent>
|
|
54
|
-
) => {
|
|
55
|
-
PageTransition(e, router, href)
|
|
56
|
-
}
|
|
57
|
-
return (
|
|
58
|
-
<Link
|
|
59
|
-
{...props}
|
|
60
|
-
href={href}
|
|
61
|
-
onClick={handleTransitionLocal}
|
|
62
|
-
className={className}
|
|
63
|
-
>
|
|
64
|
-
{children}
|
|
65
|
-
</Link>
|
|
66
|
-
)
|
|
67
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { cn } from '@/lib/utils'
|
|
4
|
-
import { Button, type ButtonProps } from '@/components/ui/button'
|
|
5
|
-
import {
|
|
6
|
-
Tooltip,
|
|
7
|
-
TooltipContent,
|
|
8
|
-
TooltipProvider,
|
|
9
|
-
TooltipTrigger,
|
|
10
|
-
} from '@/components/ui/tooltip'
|
|
11
|
-
import { Check, Copy as CopyIcon } from 'lucide-react'
|
|
12
|
-
import { useState } from 'react'
|
|
13
|
-
import { toast } from '@/hooks/use-toast'
|
|
14
|
-
|
|
15
|
-
type TCopy = {
|
|
16
|
-
copyContent: string
|
|
17
|
-
className?: string
|
|
18
|
-
iconClassName?: string
|
|
19
|
-
children?: React.ReactNode
|
|
20
|
-
} & ButtonProps
|
|
21
|
-
|
|
22
|
-
export function CopyButton({
|
|
23
|
-
copyContent,
|
|
24
|
-
className,
|
|
25
|
-
variant,
|
|
26
|
-
iconClassName,
|
|
27
|
-
size = 'icon',
|
|
28
|
-
children,
|
|
29
|
-
...props
|
|
30
|
-
}: TCopy) {
|
|
31
|
-
const [copied, setCopied] = useState<boolean>(false)
|
|
32
|
-
|
|
33
|
-
const handleCopy = async () => {
|
|
34
|
-
try {
|
|
35
|
-
await navigator.clipboard.writeText(copyContent)
|
|
36
|
-
toast({
|
|
37
|
-
title: 'Copied!',
|
|
38
|
-
description: `Content: ${copyContent}`,
|
|
39
|
-
})
|
|
40
|
-
setCopied(true)
|
|
41
|
-
setTimeout(() => setCopied(false), 1500)
|
|
42
|
-
} catch (err) {
|
|
43
|
-
console.error('Failed to copy: ', err)
|
|
44
|
-
toast({
|
|
45
|
-
title: 'Error',
|
|
46
|
-
description: 'Failed to copy the link. Please try again.',
|
|
47
|
-
variant: 'destructive',
|
|
48
|
-
})
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<TooltipProvider delayDuration={0}>
|
|
54
|
-
<Tooltip>
|
|
55
|
-
<TooltipTrigger asChild>
|
|
56
|
-
<Button
|
|
57
|
-
variant={variant}
|
|
58
|
-
size={size}
|
|
59
|
-
className={cn(
|
|
60
|
-
'flex items-center gap-2 px-4 disabled:opacity-100',
|
|
61
|
-
className
|
|
62
|
-
)}
|
|
63
|
-
onClick={handleCopy}
|
|
64
|
-
aria-label={copied ? 'Copied' : 'Copy to clipboard'}
|
|
65
|
-
disabled={copied}
|
|
66
|
-
{...props}
|
|
67
|
-
>
|
|
68
|
-
<div className={cn('relative size-4 h-full w-full transition-all')}>
|
|
69
|
-
<Check
|
|
70
|
-
className={cn(
|
|
71
|
-
'absolute left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%] stroke-emerald-500 transition-all',
|
|
72
|
-
iconClassName,
|
|
73
|
-
copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'
|
|
74
|
-
)}
|
|
75
|
-
size={16}
|
|
76
|
-
strokeWidth={3}
|
|
77
|
-
aria-hidden="true"
|
|
78
|
-
/>
|
|
79
|
-
<CopyIcon
|
|
80
|
-
size={16}
|
|
81
|
-
strokeWidth={2}
|
|
82
|
-
aria-hidden="true"
|
|
83
|
-
className={cn(
|
|
84
|
-
'absolute left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%] transition-all',
|
|
85
|
-
copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'
|
|
86
|
-
)}
|
|
87
|
-
/>
|
|
88
|
-
</div>
|
|
89
|
-
{children}
|
|
90
|
-
</Button>
|
|
91
|
-
</TooltipTrigger>
|
|
92
|
-
<TooltipContent className="z-50 px-2 py-1 text-xs" showArrow={true}>
|
|
93
|
-
Click to copy
|
|
94
|
-
</TooltipContent>
|
|
95
|
-
</Tooltip>
|
|
96
|
-
</TooltipProvider>
|
|
97
|
-
)
|
|
98
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// component to check feature flags before rendering a component
|
|
2
|
-
import * as featureflags from '@/lib/config/featureflags'
|
|
3
|
-
import { getUser } from '@/lib/config/user'
|
|
4
|
-
import type { ReactNode } from 'react'
|
|
5
|
-
|
|
6
|
-
export function FeatureFlag({
|
|
7
|
-
featureFlag,
|
|
8
|
-
children,
|
|
9
|
-
}: {
|
|
10
|
-
featureFlag: featureflags.FeatureFlagName | featureflags.FeatureFlagName[]
|
|
11
|
-
children: ReactNode
|
|
12
|
-
}) {
|
|
13
|
-
const user = getUser()
|
|
14
|
-
|
|
15
|
-
if (Array.isArray(featureFlag)) {
|
|
16
|
-
return featureFlag.every((flag) => featureflags.canViewFeature(flag, user))
|
|
17
|
-
? children
|
|
18
|
-
: null
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return featureflags.canViewFeature(featureFlag, user) ? children : null
|
|
22
|
-
}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
type IconProps = React.HTMLAttributes<SVGElement>
|
|
2
|
-
// custom svg icons
|
|
3
|
-
export const Icons = {
|
|
4
|
-
twitter: (props: IconProps) => (
|
|
5
|
-
<svg
|
|
6
|
-
{...props}
|
|
7
|
-
height="23"
|
|
8
|
-
viewBox="0 0 1200 1227"
|
|
9
|
-
width="23"
|
|
10
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
-
>
|
|
12
|
-
<path d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z" />
|
|
13
|
-
</svg>
|
|
14
|
-
),
|
|
15
|
-
gitHub: (props: IconProps) => (
|
|
16
|
-
<svg viewBox="0 0 438.549 438.549" {...props}>
|
|
17
|
-
<path
|
|
18
|
-
fill="currentColor"
|
|
19
|
-
d="M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z"
|
|
20
|
-
></path>
|
|
21
|
-
</svg>
|
|
22
|
-
),
|
|
23
|
-
radix: (props: IconProps) => (
|
|
24
|
-
<svg viewBox="0 0 25 25" fill="none" {...props}>
|
|
25
|
-
<path
|
|
26
|
-
d="M12 25C7.58173 25 4 21.4183 4 17C4 12.5817 7.58173 9 12 9V25Z"
|
|
27
|
-
fill="currentcolor"
|
|
28
|
-
></path>
|
|
29
|
-
<path d="M12 0H4V8H12V0Z" fill="currentcolor"></path>
|
|
30
|
-
<path
|
|
31
|
-
d="M17 8C19.2091 8 21 6.20914 21 4C21 1.79086 19.2091 0 17 0C14.7909 0 13 1.79086 13 4C13 6.20914 14.7909 8 17 8Z"
|
|
32
|
-
fill="currentcolor"
|
|
33
|
-
></path>
|
|
34
|
-
</svg>
|
|
35
|
-
),
|
|
36
|
-
aria: (props: IconProps) => (
|
|
37
|
-
<svg role="img" viewBox="0 0 24 24" fill="currentColor" {...props}>
|
|
38
|
-
<path d="M13.966 22.624l-1.69-4.281H8.122l3.892-9.144 5.662 13.425zM8.884 1.376H0v21.248zm15.116 0h-8.884L24 22.624Z" />
|
|
39
|
-
</svg>
|
|
40
|
-
),
|
|
41
|
-
npm: (props: IconProps) => (
|
|
42
|
-
<svg viewBox="0 0 24 24" {...props}>
|
|
43
|
-
<path
|
|
44
|
-
d="M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z"
|
|
45
|
-
fill="currentColor"
|
|
46
|
-
/>
|
|
47
|
-
</svg>
|
|
48
|
-
),
|
|
49
|
-
yarn: (props: IconProps) => (
|
|
50
|
-
<svg viewBox="0 0 24 24" {...props}>
|
|
51
|
-
<path
|
|
52
|
-
d="M12 0C5.375 0 0 5.375 0 12s5.375 12 12 12 12-5.375 12-12S18.625 0 12 0zm.768 4.105c.183 0 .363.053.525.157.125.083.287.185.755 1.154.31-.088.468-.042.551-.019.204.056.366.19.463.375.477.917.542 2.553.334 3.605-.241 1.232-.755 2.029-1.131 2.576.324.329.778.899 1.117 1.825.278.774.31 1.478.273 2.015a5.51 5.51 0 0 0 .602-.329c.593-.366 1.487-.917 2.553-.931.714-.009 1.269.445 1.353 1.103a1.23 1.23 0 0 1-.945 1.362c-.649.158-.95.278-1.821.843-1.232.797-2.539 1.242-3.012 1.39a1.686 1.686 0 0 1-.704.343c-.737.181-3.266.315-3.466.315h-.046c-.783 0-1.214-.241-1.45-.491-.658.329-1.51.19-2.122-.134a1.078 1.078 0 0 1-.58-1.153 1.243 1.243 0 0 1-.153-.195c-.162-.25-.528-.936-.454-1.946.056-.723.556-1.367.88-1.71a5.522 5.522 0 0 1 .408-2.256c.306-.727.885-1.348 1.32-1.737-.32-.537-.644-1.367-.329-2.21.227-.602.412-.936.82-1.08h-.005c.199-.074.389-.153.486-.259a3.418 3.418 0 0 1 2.298-1.103c.037-.093.079-.185.125-.283.31-.658.639-1.029 1.024-1.168a.94.94 0 0 1 .328-.06zm.006.7c-.507.016-1.001 1.519-1.001 1.519s-1.27-.204-2.266.871c-.199.218-.468.334-.746.44-.079.028-.176.023-.417.672-.371.991.625 2.094.625 2.094s-1.186.839-1.626 1.881c-.486 1.144-.338 2.261-.338 2.261s-.843.732-.899 1.487c-.051.663.139 1.2.343 1.515.227.343.51.176.51.176s-.561.653-.037.931c.477.25 1.283.394 1.71-.037.31-.31.371-1.001.486-1.283.028-.065.12.111.209.199.097.093.264.195.264.195s-.755.324-.445 1.066c.102.246.468.403 1.066.398.222-.005 2.664-.139 3.313-.296.375-.088.505-.283.505-.283s1.566-.431 2.998-1.357c.917-.598 1.293-.76 2.034-.936.612-.148.57-1.098-.241-1.084-.839.009-1.575.44-2.196.825-1.163.718-1.742.672-1.742.672l-.018-.032c-.079-.13.371-1.293-.134-2.678-.547-1.515-1.413-1.881-1.344-1.997.297-.5 1.038-1.297 1.334-2.78.176-.899.13-2.377-.269-3.151-.074-.144-.732.241-.732.241s-.616-1.371-.788-1.483a.271.271 0 0 0-.157-.046z"
|
|
53
|
-
fill="currentColor"
|
|
54
|
-
/>
|
|
55
|
-
</svg>
|
|
56
|
-
),
|
|
57
|
-
pnpm: (props: IconProps) => (
|
|
58
|
-
<svg viewBox="0 0 24 24" {...props}>
|
|
59
|
-
<path
|
|
60
|
-
d="M0 0v7.5h7.5V0zm8.25 0v7.5h7.498V0zm8.25 0v7.5H24V0zM8.25 8.25v7.5h7.498v-7.5zm8.25 0v7.5H24v-7.5zM0 16.5V24h7.5v-7.5zm8.25 0V24h7.498v-7.5zm8.25 0V24H24v-7.5z"
|
|
61
|
-
fill="currentColor"
|
|
62
|
-
/>
|
|
63
|
-
</svg>
|
|
64
|
-
),
|
|
65
|
-
react: (props: IconProps) => (
|
|
66
|
-
<svg viewBox="0 0 24 24" {...props}>
|
|
67
|
-
<path
|
|
68
|
-
d="M14.23 12.004a2.236 2.236 0 0 1-2.235 2.236 2.236 2.236 0 0 1-2.236-2.236 2.236 2.236 0 0 1 2.235-2.236 2.236 2.236 0 0 1 2.236 2.236zm2.648-10.69c-1.346 0-3.107.96-4.888 2.622-1.78-1.653-3.542-2.602-4.887-2.602-.41 0-.783.093-1.106.278-1.375.793-1.683 3.264-.973 6.365C1.98 8.917 0 10.42 0 12.004c0 1.59 1.99 3.097 5.043 4.03-.704 3.113-.39 5.588.988 6.38.32.187.69.275 1.102.275 1.345 0 3.107-.96 4.888-2.624 1.78 1.654 3.542 2.603 4.887 2.603.41 0 .783-.09 1.106-.275 1.374-.792 1.683-3.263.973-6.365C22.02 15.096 24 13.59 24 12.004c0-1.59-1.99-3.097-5.043-4.032.704-3.11.39-5.587-.988-6.38-.318-.184-.688-.277-1.092-.278zm-.005 1.09v.006c.225 0 .406.044.558.127.666.382.955 1.835.73 3.704-.054.46-.142.945-.25 1.44-.96-.236-2.006-.417-3.107-.534-.66-.905-1.345-1.727-2.035-2.447 1.592-1.48 3.087-2.292 4.105-2.295zm-9.77.02c1.012 0 2.514.808 4.11 2.28-.686.72-1.37 1.537-2.02 2.442-1.107.117-2.154.298-3.113.538-.112-.49-.195-.964-.254-1.42-.23-1.868.054-3.32.714-3.707.19-.09.4-.127.563-.132zm4.882 3.05c.455.468.91.992 1.36 1.564-.44-.02-.89-.034-1.345-.034-.46 0-.915.01-1.36.034.44-.572.895-1.096 1.345-1.565zM12 8.1c.74 0 1.477.034 2.202.093.406.582.802 1.203 1.183 1.86.372.64.71 1.29 1.018 1.946-.308.655-.646 1.31-1.013 1.95-.38.66-.773 1.288-1.18 1.87-.728.063-1.466.098-2.21.098-.74 0-1.477-.035-2.202-.093-.406-.582-.802-1.204-1.183-1.86-.372-.64-.71-1.29-1.018-1.946.303-.657.646-1.313 1.013-1.954.38-.66.773-1.286 1.18-1.868.728-.064 1.466-.098 2.21-.098zm-3.635.254c-.24.377-.48.763-.704 1.16-.225.39-.435.782-.635 1.174-.265-.656-.49-1.31-.676-1.947.64-.15 1.315-.283 2.015-.386zm7.26 0c.695.103 1.365.23 2.006.387-.18.632-.405 1.282-.66 1.933-.2-.39-.41-.783-.64-1.174-.225-.392-.465-.774-.705-1.146zm3.063.675c.484.15.944.317 1.375.498 1.732.74 2.852 1.708 2.852 2.476-.005.768-1.125 1.74-2.857 2.475-.42.18-.88.342-1.355.493-.28-.958-.646-1.956-1.1-2.98.45-1.017.81-2.01 1.085-2.964zm-13.395.004c.278.96.645 1.957 1.1 2.98-.45 1.017-.812 2.01-1.086 2.964-.484-.15-.944-.318-1.37-.5-1.732-.737-2.852-1.706-2.852-2.474 0-.768 1.12-1.742 2.852-2.476.42-.18.88-.342 1.356-.494zm11.678 4.28c.265.657.49 1.312.676 1.948-.64.157-1.316.29-2.016.39.24-.375.48-.762.705-1.158.225-.39.435-.788.636-1.18zm-9.945.02c.2.392.41.783.64 1.175.23.39.465.772.705 1.143-.695-.102-1.365-.23-2.006-.386.18-.63.406-1.282.66-1.933zM17.92 16.32c.112.493.2.968.254 1.423.23 1.868-.054 3.32-.714 3.708-.147.09-.338.128-.563.128-1.012 0-2.514-.807-4.11-2.28.686-.72 1.37-1.536 2.02-2.44 1.107-.118 2.154-.3 3.113-.54zm-11.83.01c.96.234 2.006.415 3.107.532.66.905 1.345 1.727 2.035 2.446-1.595 1.483-3.092 2.295-4.11 2.295-.22-.005-.406-.05-.553-.132-.666-.38-.955-1.834-.73-3.703.054-.46.142-.944.25-1.438zm4.56.64c.44.02.89.034 1.345.034.46 0 .915-.01 1.36-.034-.44.572-.895 1.095-1.345 1.565-.455-.47-.91-.993-1.36-1.565z"
|
|
69
|
-
fill="currentColor"
|
|
70
|
-
/>
|
|
71
|
-
</svg>
|
|
72
|
-
),
|
|
73
|
-
tailwind: (props: IconProps) => (
|
|
74
|
-
<svg viewBox="0 0 24 24" {...props}>
|
|
75
|
-
<path
|
|
76
|
-
d="M12.001,4.8c-3.2,0-5.2,1.6-6,4.8c1.2-1.6,2.6-2.2,4.2-1.8c0.913,0.228,1.565,0.89,2.288,1.624 C13.666,10.618,15.027,12,18.001,12c3.2,0,5.2-1.6,6-4.8c-1.2,1.6-2.6,2.2-4.2,1.8c-0.913-0.228-1.565-0.89-2.288-1.624 C16.337,6.182,14.976,4.8,12.001,4.8z M6.001,12c-3.2,0-5.2,1.6-6,4.8c1.2-1.6,2.6-2.2,4.2-1.8c0.913,0.228,1.565,0.89,2.288,1.624 c1.177,1.194,2.538,2.576,5.512,2.576c3.2,0,5.2-1.6,6-4.8c-1.2,1.6-2.6,2.2-4.2,1.8c-0.913-0.228-1.565-0.89-2.288-1.624 C10.337,13.382,8.976,12,6.001,12z"
|
|
77
|
-
fill="currentColor"
|
|
78
|
-
/>
|
|
79
|
-
</svg>
|
|
80
|
-
),
|
|
81
|
-
google: (props: IconProps) => (
|
|
82
|
-
<svg role="img" viewBox="0 0 24 24" {...props}>
|
|
83
|
-
<path
|
|
84
|
-
fill="currentColor"
|
|
85
|
-
d="M12.48 10.92v3.28h7.84c-.24 1.84-.853 3.187-1.787 4.133-1.147 1.147-2.933 2.4-6.053 2.4-4.827 0-8.6-3.893-8.6-8.72s3.773-8.72 8.6-8.72c2.6 0 4.507 1.027 5.907 2.347l2.307-2.307C18.747 1.44 16.133 0 12.48 0 5.867 0 .307 5.387.307 12s5.56 12 12.173 12c3.573 0 6.267-1.173 8.373-3.36 2.16-2.16 2.84-5.213 2.84-7.667 0-.76-.053-1.467-.173-2.053H12.48z"
|
|
86
|
-
/>
|
|
87
|
-
</svg>
|
|
88
|
-
),
|
|
89
|
-
apple: (props: IconProps) => (
|
|
90
|
-
<svg role="img" viewBox="0 0 24 24" {...props}>
|
|
91
|
-
<path
|
|
92
|
-
d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701"
|
|
93
|
-
fill="currentColor"
|
|
94
|
-
/>
|
|
95
|
-
</svg>
|
|
96
|
-
),
|
|
97
|
-
paypal: (props: IconProps) => (
|
|
98
|
-
<svg role="img" viewBox="0 0 24 24" {...props}>
|
|
99
|
-
<path
|
|
100
|
-
d="M7.076 21.337H2.47a.641.641 0 0 1-.633-.74L4.944.901C5.026.382 5.474 0 5.998 0h7.46c2.57 0 4.578.543 5.69 1.81 1.01 1.15 1.304 2.42 1.012 4.287-.023.143-.047.288-.077.437-.983 5.05-4.349 6.797-8.647 6.797h-2.19c-.524 0-.968.382-1.05.9l-1.12 7.106zm14.146-14.42a3.35 3.35 0 0 0-.607-.541c-.013.076-.026.175-.041.254-.93 4.778-4.005 7.201-9.138 7.201h-2.19a.563.563 0 0 0-.556.479l-1.187 7.527h-.506l-.24 1.516a.56.56 0 0 0 .554.647h3.882c.46 0 .85-.334.922-.788.06-.26.76-4.852.816-5.09a.932.932 0 0 1 .923-.788h.58c3.76 0 6.705-1.528 7.565-5.946.36-1.847.174-3.388-.777-4.471z"
|
|
101
|
-
fill="currentColor"
|
|
102
|
-
/>
|
|
103
|
-
</svg>
|
|
104
|
-
),
|
|
105
|
-
spinner: (props: IconProps) => (
|
|
106
|
-
<svg
|
|
107
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
108
|
-
width="24"
|
|
109
|
-
height="24"
|
|
110
|
-
viewBox="0 0 24 24"
|
|
111
|
-
fill="none"
|
|
112
|
-
stroke="currentColor"
|
|
113
|
-
strokeWidth="2"
|
|
114
|
-
strokeLinecap="round"
|
|
115
|
-
strokeLinejoin="round"
|
|
116
|
-
{...props}
|
|
117
|
-
>
|
|
118
|
-
<path d="M21 12a9 9 0 1 1-6.219-8.56" />
|
|
119
|
-
</svg>
|
|
120
|
-
),
|
|
121
|
-
youtube: (props: IconProps) => (
|
|
122
|
-
<svg
|
|
123
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
124
|
-
width="24"
|
|
125
|
-
height="24"
|
|
126
|
-
viewBox="0 0 24 24"
|
|
127
|
-
{...props}
|
|
128
|
-
>
|
|
129
|
-
<path d="M21.593 7.203a2.506 2.506 0 0 0-1.762-1.766C18.265 5.007 12 5 12 5s-6.264-.007-7.831.404a2.56 2.56 0 0 0-1.766 1.778c-.413 1.566-.417 4.814-.417 4.814s-.004 3.264.406 4.814c.23.857.905 1.534 1.763 1.765 1.582.43 7.83.437 7.83.437s6.265.007 7.831-.403a2.515 2.515 0 0 0 1.767-1.763c.414-1.565.417-4.812.417-4.812s.02-3.265-.407-4.831zM9.996 15.005l.005-6 5.207 3.005-5.212 2.995z"></path>
|
|
130
|
-
</svg>
|
|
131
|
-
),
|
|
132
|
-
facebook: (props: IconProps) => (
|
|
133
|
-
<svg
|
|
134
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
135
|
-
width="24"
|
|
136
|
-
height="24"
|
|
137
|
-
viewBox="0 0 24 24"
|
|
138
|
-
{...props}
|
|
139
|
-
>
|
|
140
|
-
<path d="M12.001 2.002c-5.522 0-9.999 4.477-9.999 9.999 0 4.99 3.656 9.126 8.437 9.879v-6.988h-2.54v-2.891h2.54V9.798c0-2.508 1.493-3.891 3.776-3.891 1.094 0 2.24.195 2.24.195v2.459h-1.264c-1.24 0-1.628.772-1.628 1.563v1.875h2.771l-.443 2.891h-2.328v6.988C18.344 21.129 22 16.992 22 12.001c0-5.522-4.477-9.999-9.999-9.999z"></path>
|
|
141
|
-
</svg>
|
|
142
|
-
),
|
|
143
|
-
linkedin: (props: IconProps) => (
|
|
144
|
-
<svg
|
|
145
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
146
|
-
width="24"
|
|
147
|
-
height="24"
|
|
148
|
-
viewBox="0 0 24 24"
|
|
149
|
-
{...props}
|
|
150
|
-
>
|
|
151
|
-
<circle cx="4.983" cy="5.009" r="2.188"></circle>
|
|
152
|
-
<path d="M9.237 8.855v12.139h3.769v-6.003c0-1.584.298-3.118 2.262-3.118 1.937 0 1.961 1.811 1.961 3.218v5.904H21v-6.657c0-3.27-.704-5.783-4.526-5.783-1.835 0-3.065 1.007-3.568 1.96h-.051v-1.66H9.237zm-6.142 0H6.87v12.139H3.095z"></path>
|
|
153
|
-
</svg>
|
|
154
|
-
),
|
|
155
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
// a share modal with qr, fb, twitter/x, linkedin
|
|
3
|
-
import { getQrCode } from '@/lib/utils'
|
|
4
|
-
// components
|
|
5
|
-
import { Img } from '@/components/utils/Img'
|
|
6
|
-
import { Button } from '@/components/ui/button'
|
|
7
|
-
import {
|
|
8
|
-
Drawer,
|
|
9
|
-
DrawerClose,
|
|
10
|
-
DrawerContent,
|
|
11
|
-
DrawerFooter,
|
|
12
|
-
DrawerTrigger,
|
|
13
|
-
DrawerTitle,
|
|
14
|
-
} from '@/components/ui/drawer'
|
|
15
|
-
import { Input } from '@/components/ui/input'
|
|
16
|
-
import { Icons } from '@/components/utils/icons'
|
|
17
|
-
import { CopyButton } from '@/components/utils/copy'
|
|
18
|
-
|
|
19
|
-
type ShareModalProps = React.ComponentProps<typeof Drawer> & {
|
|
20
|
-
shareUrl: string
|
|
21
|
-
sharetoWindow?: boolean
|
|
22
|
-
twText?: string
|
|
23
|
-
// change your qr icon in src/components/utils/icons.tsx
|
|
24
|
-
qrIcon?: React.ReactNode
|
|
25
|
-
title?: string
|
|
26
|
-
}
|
|
27
|
-
export function ShareModal({
|
|
28
|
-
children,
|
|
29
|
-
shareUrl,
|
|
30
|
-
sharetoWindow,
|
|
31
|
-
twText,
|
|
32
|
-
qrIcon,
|
|
33
|
-
title = 'Share with friends',
|
|
34
|
-
...props
|
|
35
|
-
}: ShareModalProps) {
|
|
36
|
-
// const copyToClipboard = async () => {
|
|
37
|
-
// try {
|
|
38
|
-
// await navigator.clipboard.writeText(shareUrl);
|
|
39
|
-
// toast({
|
|
40
|
-
// title: "Copied!",
|
|
41
|
-
// description: `URL: ${shareUrl}`,
|
|
42
|
-
// });
|
|
43
|
-
// } catch (err) {
|
|
44
|
-
// console.error("Failed to copy: ", err);
|
|
45
|
-
// toast({
|
|
46
|
-
// title: "Error",
|
|
47
|
-
// description: "Failed to copy the link. Please try again.",
|
|
48
|
-
// variant: "destructive",
|
|
49
|
-
// });
|
|
50
|
-
// }
|
|
51
|
-
// };
|
|
52
|
-
|
|
53
|
-
const shareToSocial = (platform: string) => {
|
|
54
|
-
let url = ''
|
|
55
|
-
const encodedUrl = encodeURIComponent(shareUrl)
|
|
56
|
-
const twitterText = twText ? encodeURIComponent(twText) : ''
|
|
57
|
-
|
|
58
|
-
switch (platform) {
|
|
59
|
-
case 'facebook':
|
|
60
|
-
url = `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`
|
|
61
|
-
break
|
|
62
|
-
|
|
63
|
-
case 'twitter':
|
|
64
|
-
url = `https://twitter.com/intent/tweet?text=${twitterText}&url=${encodedUrl}`
|
|
65
|
-
break
|
|
66
|
-
case 'linkedin':
|
|
67
|
-
url = `https://www.linkedin.com/sharing/share-offsite/?url=${encodedUrl}`
|
|
68
|
-
break
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Open in a new window with specific dimensions
|
|
72
|
-
const width = 600
|
|
73
|
-
const height = 400
|
|
74
|
-
const left = window.innerWidth / 2 - width / 2
|
|
75
|
-
const top = window.innerHeight / 2 - height / 2
|
|
76
|
-
|
|
77
|
-
window.open(
|
|
78
|
-
url,
|
|
79
|
-
'_blank',
|
|
80
|
-
sharetoWindow
|
|
81
|
-
? `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${width}, height=${height}, top=${top}, left=${left}`
|
|
82
|
-
: undefined
|
|
83
|
-
)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const iconClassName = 'size-6 md:size-5 fill-foreground'
|
|
87
|
-
const buttonClassName = 'grow group'
|
|
88
|
-
return (
|
|
89
|
-
<Drawer {...props}>
|
|
90
|
-
<DrawerTrigger asChild>{children}</DrawerTrigger>
|
|
91
|
-
<DrawerContent>
|
|
92
|
-
<div className="mx-auto max-w-xl">
|
|
93
|
-
<div className="flex-row-reverse place-content-center items-center gap-4 space-y-6 p-4 md:flex">
|
|
94
|
-
<div>
|
|
95
|
-
<DrawerTitle className="text-2xl font-medium">
|
|
96
|
-
{title}
|
|
97
|
-
</DrawerTitle>
|
|
98
|
-
<div className="mb-2 flex items-center space-x-2">
|
|
99
|
-
<Input
|
|
100
|
-
value={shareUrl?.toString()}
|
|
101
|
-
readOnly
|
|
102
|
-
className="text-xm flex-grow"
|
|
103
|
-
/>
|
|
104
|
-
{/* <Button onClick={copyToClipboard} className="px-6">
|
|
105
|
-
<Copy className="h-4 w-4 " />
|
|
106
|
-
Copy
|
|
107
|
-
</Button> */}
|
|
108
|
-
<CopyButton copyContent={shareUrl} />
|
|
109
|
-
</div>
|
|
110
|
-
<div className="flex justify-center space-x-4">
|
|
111
|
-
<Button
|
|
112
|
-
onClick={() => shareToSocial('facebook')}
|
|
113
|
-
variant="outline"
|
|
114
|
-
className={buttonClassName}
|
|
115
|
-
>
|
|
116
|
-
<Icons.facebook className={iconClassName} />
|
|
117
|
-
</Button>
|
|
118
|
-
|
|
119
|
-
<Button
|
|
120
|
-
onClick={() => shareToSocial('twitter')}
|
|
121
|
-
variant="outline"
|
|
122
|
-
className={buttonClassName}
|
|
123
|
-
>
|
|
124
|
-
<Icons.twitter className={iconClassName} />
|
|
125
|
-
</Button>
|
|
126
|
-
<Button
|
|
127
|
-
onClick={() => shareToSocial('linkedin')}
|
|
128
|
-
variant="outline"
|
|
129
|
-
className={buttonClassName}
|
|
130
|
-
>
|
|
131
|
-
<Icons.linkedin className={iconClassName} />
|
|
132
|
-
</Button>
|
|
133
|
-
</div>
|
|
134
|
-
</div>
|
|
135
|
-
|
|
136
|
-
<div className="flex justify-center">
|
|
137
|
-
{qrIcon ? (
|
|
138
|
-
<div className="size-64 md:size-52">{qrIcon}</div>
|
|
139
|
-
) : (
|
|
140
|
-
<Img
|
|
141
|
-
src={getQrCode(shareUrl)}
|
|
142
|
-
alt="a2e-qr"
|
|
143
|
-
width={256}
|
|
144
|
-
height={256}
|
|
145
|
-
className="size-64 rounded-lg dark:invert md:size-52"
|
|
146
|
-
/>
|
|
147
|
-
)}
|
|
148
|
-
</div>
|
|
149
|
-
</div>
|
|
150
|
-
<DrawerFooter className="mt-0 pt-0">
|
|
151
|
-
<DrawerClose asChild>
|
|
152
|
-
<Button variant="outline">Close</Button>
|
|
153
|
-
</DrawerClose>
|
|
154
|
-
</DrawerFooter>
|
|
155
|
-
</div>
|
|
156
|
-
</DrawerContent>
|
|
157
|
-
</Drawer>
|
|
158
|
-
)
|
|
159
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
// a hook for animating elements when they enter the viewport (intErsection observer)
|
|
3
|
-
// - must be used in a client component
|
|
4
|
-
// const { ref, isInView } = useIntersection({ threshold: 0.2, once: true });
|
|
5
|
-
// <div ref={ref} className={cn(isInView && 'motion-blur-in-[50px]')}>
|
|
6
|
-
import { useEffect, useRef, useState } from 'react'
|
|
7
|
-
|
|
8
|
-
interface UseIntersectionOptions {
|
|
9
|
-
threshold?: number
|
|
10
|
-
root?: Element | null
|
|
11
|
-
rootMargin?: string
|
|
12
|
-
once?: boolean
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function useIntersection({
|
|
16
|
-
threshold = 0,
|
|
17
|
-
root = null,
|
|
18
|
-
rootMargin = '0px',
|
|
19
|
-
once = false,
|
|
20
|
-
}: UseIntersectionOptions = {}) {
|
|
21
|
-
const [isInView, setIsInView] = useState(false)
|
|
22
|
-
const ref = useRef<HTMLDivElement>(null)
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
const element = ref.current
|
|
26
|
-
const observer = new IntersectionObserver(
|
|
27
|
-
([entry]) => {
|
|
28
|
-
if (entry.isIntersecting) {
|
|
29
|
-
setIsInView(true)
|
|
30
|
-
if (once && element) {
|
|
31
|
-
observer.unobserve(element)
|
|
32
|
-
}
|
|
33
|
-
} else if (!once) {
|
|
34
|
-
setIsInView(false)
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
{ threshold, root, rootMargin }
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
if (element) {
|
|
41
|
-
observer.observe(element)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return () => {
|
|
45
|
-
if (element) {
|
|
46
|
-
observer.unobserve(element)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}, [threshold, root, rootMargin, once])
|
|
50
|
-
|
|
51
|
-
return { ref, isInView }
|
|
52
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect, useRef } from 'react'
|
|
2
|
-
|
|
3
|
-
export function useLazyLoad() {
|
|
4
|
-
const [isIntersecting, setIntersecting] = useState(false)
|
|
5
|
-
const ref = useRef<HTMLDivElement>(null)
|
|
6
|
-
|
|
7
|
-
useEffect(() => {
|
|
8
|
-
const element = ref.current
|
|
9
|
-
const observer = new IntersectionObserver(
|
|
10
|
-
([entry]) => {
|
|
11
|
-
if (entry.isIntersecting) {
|
|
12
|
-
setIntersecting(true)
|
|
13
|
-
observer.unobserve(entry.target)
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
rootMargin: '200px',
|
|
18
|
-
}
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
if (element) {
|
|
22
|
-
observer.observe(element)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return () => {
|
|
26
|
-
if (element) {
|
|
27
|
-
observer.unobserve(element)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}, [])
|
|
31
|
-
|
|
32
|
-
return [ref, isIntersecting] as const
|
|
33
|
-
}
|