@ardly/bunext 1.0.5 → 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.
Files changed (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +33 -16
  3. package/cli.mjs +126 -0
  4. package/package.json +14 -58
  5. package/.eslintrc.json +0 -8
  6. package/.prettierignore +0 -4
  7. package/STRUCTURE.md +0 -77
  8. package/bin/cli.mjs +0 -133
  9. package/bin/utils.mjs +0 -32
  10. package/components.json +0 -21
  11. package/next.config.ts +0 -22
  12. package/postcss.config.mjs +0 -8
  13. package/prettier.config.js +0 -7
  14. package/public/android-chrome-192x192.png +0 -0
  15. package/public/android-chrome-512x512.png +0 -0
  16. package/public/favicon.svg +0 -1
  17. package/public/loading-dots.gif +0 -0
  18. package/public/logo.svg +0 -1
  19. package/public/ogImage.webp +0 -0
  20. package/public/site.webmanifest +0 -19
  21. package/src/actions/placeholder.ts +0 -30
  22. package/src/actions/sampleAction.ts +0 -39
  23. package/src/app/(index)/intr/TestCard.tsx +0 -31
  24. package/src/app/(index)/intr/page.tsx +0 -17
  25. package/src/app/(index)/page.tsx +0 -156
  26. package/src/app/(index)/pagetr/page.tsx +0 -37
  27. package/src/app/error-wrapper.tsx +0 -32
  28. package/src/app/global-error.tsx +0 -53
  29. package/src/app/layout.tsx +0 -56
  30. package/src/app/loading.tsx +0 -11
  31. package/src/app/not-found.tsx +0 -45
  32. package/src/app/sitemap.ts +0 -14
  33. package/src/components/Providers/root-provider.tsx +0 -22
  34. package/src/components/Providers/theme-provider.tsx +0 -27
  35. package/src/components/TestComp.tsx +0 -11
  36. package/src/components/brand.tsx +0 -35
  37. package/src/components/navigation/footer.tsx +0 -32
  38. package/src/components/navigation/main-nav.tsx +0 -55
  39. package/src/components/navigation/mobile-nav.tsx +0 -154
  40. package/src/components/navigation/site-header.tsx +0 -67
  41. package/src/components/ui/avatar.tsx +0 -50
  42. package/src/components/ui/badge.tsx +0 -36
  43. package/src/components/ui/button.tsx +0 -56
  44. package/src/components/ui/card.tsx +0 -79
  45. package/src/components/ui/command.tsx +0 -153
  46. package/src/components/ui/dialog.tsx +0 -122
  47. package/src/components/ui/drawer.tsx +0 -118
  48. package/src/components/ui/dropdown-menu.tsx +0 -200
  49. package/src/components/ui/input.tsx +0 -22
  50. package/src/components/ui/label.tsx +0 -26
  51. package/src/components/ui/multi-select.tsx +0 -380
  52. package/src/components/ui/origin/multiselect.tsx +0 -645
  53. package/src/components/ui/popover.tsx +0 -31
  54. package/src/components/ui/radio-group.tsx +0 -44
  55. package/src/components/ui/separator.tsx +0 -31
  56. package/src/components/ui/skeleton.tsx +0 -15
  57. package/src/components/ui/themeSelector.tsx +0 -157
  58. package/src/components/ui/toast.tsx +0 -129
  59. package/src/components/ui/toaster.tsx +0 -31
  60. package/src/components/ui/tooltip.tsx +0 -39
  61. package/src/components/utils/ConditionalLink.tsx +0 -46
  62. package/src/components/utils/Image.tsx +0 -57
  63. package/src/components/utils/Img.tsx +0 -104
  64. package/src/components/utils/Spinner.tsx +0 -29
  65. package/src/components/utils/TopButton.tsx +0 -67
  66. package/src/components/utils/TransitionLink.tsx +0 -67
  67. package/src/components/utils/copy.tsx +0 -98
  68. package/src/components/utils/featureFlag.tsx +0 -22
  69. package/src/components/utils/icons.tsx +0 -155
  70. package/src/components/utils/share-modal.tsx +0 -159
  71. package/src/hooks/use-intersection.ts +0 -52
  72. package/src/hooks/use-lazy-load.ts +0 -33
  73. package/src/hooks/use-meta-color.ts +0 -25
  74. package/src/hooks/use-toast.ts +0 -191
  75. package/src/lib/config/featureflags.ts +0 -63
  76. package/src/lib/config/siteConfig.ts +0 -172
  77. package/src/lib/config/user.ts +0 -9
  78. package/src/lib/data/footer-data.ts +0 -85
  79. package/src/lib/data/nav-data.ts +0 -30
  80. package/src/lib/data/siteData.ts +0 -52
  81. package/src/lib/utils/index.ts +0 -190
  82. package/src/styles/customGlobal.css +0 -141
  83. package/src/styles/globals.css +0 -72
  84. package/src/styles/tailwind/base.ts +0 -46
  85. package/src/styles/tailwind/fonts/ClashDisplay-Bold.eot +0 -0
  86. package/src/styles/tailwind/fonts/ClashDisplay-Bold.ttf +0 -0
  87. package/src/styles/tailwind/fonts/ClashDisplay-Bold.woff +0 -0
  88. package/src/styles/tailwind/fonts/ClashDisplay-Bold.woff2 +0 -0
  89. package/src/styles/tailwind/fonts/ClashDisplay-Extralight.eot +0 -0
  90. package/src/styles/tailwind/fonts/ClashDisplay-Extralight.ttf +0 -0
  91. package/src/styles/tailwind/fonts/ClashDisplay-Extralight.woff +0 -0
  92. package/src/styles/tailwind/fonts/ClashDisplay-Extralight.woff2 +0 -0
  93. package/src/styles/tailwind/fonts/ClashDisplay-Light.eot +0 -0
  94. package/src/styles/tailwind/fonts/ClashDisplay-Light.ttf +0 -0
  95. package/src/styles/tailwind/fonts/ClashDisplay-Light.woff +0 -0
  96. package/src/styles/tailwind/fonts/ClashDisplay-Light.woff2 +0 -0
  97. package/src/styles/tailwind/fonts/ClashDisplay-Medium.eot +0 -0
  98. package/src/styles/tailwind/fonts/ClashDisplay-Medium.ttf +0 -0
  99. package/src/styles/tailwind/fonts/ClashDisplay-Medium.woff +0 -0
  100. package/src/styles/tailwind/fonts/ClashDisplay-Medium.woff2 +0 -0
  101. package/src/styles/tailwind/fonts/ClashDisplay-Regular.eot +0 -0
  102. package/src/styles/tailwind/fonts/ClashDisplay-Regular.ttf +0 -0
  103. package/src/styles/tailwind/fonts/ClashDisplay-Regular.woff +0 -0
  104. package/src/styles/tailwind/fonts/ClashDisplay-Regular.woff2 +0 -0
  105. package/src/styles/tailwind/fonts/ClashDisplay-Semibold.eot +0 -0
  106. package/src/styles/tailwind/fonts/ClashDisplay-Semibold.ttf +0 -0
  107. package/src/styles/tailwind/fonts/ClashDisplay-Semibold.woff +0 -0
  108. package/src/styles/tailwind/fonts/ClashDisplay-Semibold.woff2 +0 -0
  109. package/src/styles/tailwind/fonts/ClashDisplay-Variable.eot +0 -0
  110. package/src/styles/tailwind/fonts/ClashDisplay-Variable.ttf +0 -0
  111. package/src/styles/tailwind/fonts/ClashDisplay-Variable.woff +0 -0
  112. package/src/styles/tailwind/fonts/ClashDisplay-Variable.woff2 +0 -0
  113. package/src/styles/tailwind/fonts/GeistMonoVF.woff +0 -0
  114. package/src/styles/tailwind/fonts/GeistVF.woff +0 -0
  115. package/src/styles/tailwind/fonts.ts +0 -51
  116. package/src/styles/tailwind/tailwindUtils.ts +0 -29
  117. package/src/types/index.ts +0 -80
  118. package/tailwind.config.ts +0 -104
  119. package/tsconfig.json +0 -28
  120. 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
- }