├── supabase └── .gitignore ├── components ├── ui │ ├── Avatar │ │ ├── index.ts │ │ └── Avatar.tsx │ ├── Brand │ │ └── index.ts │ ├── Button │ │ ├── index.ts │ │ └── Button.tsx │ ├── Footer │ │ └── index.ts │ ├── Input │ │ ├── index.tsx │ │ └── Input.tsx │ ├── Label │ │ ├── index.ts │ │ └── Label.tsx │ ├── Link │ │ ├── index.ts │ │ └── LinkItem.tsx │ ├── Navbar │ │ ├── index.ts │ │ └── ButtonMenu.tsx │ ├── Radio │ │ ├── index.ts │ │ └── Radio.tsx │ ├── Banner │ │ ├── index.ts │ │ └── Banner.tsx │ ├── Checkbox │ │ ├── index.ts │ │ └── Checkbox.tsx │ ├── Page404 │ │ ├── index.ts │ │ └── Page404.tsx │ ├── Textarea │ │ ├── index.ts │ │ └── Textarea.tsx │ ├── UploadAvatar │ │ ├── index.ts │ │ └── UploadAvatar.tsx │ ├── AvatarMenu │ │ ├── index.ts │ │ └── AvatarMenu.tsx │ ├── LabelError │ │ ├── index.ts │ │ └── LabelError.tsx │ ├── LinkShiny │ │ ├── index.ts │ │ └── LinkShiny.tsx │ ├── ButtonUpvote │ │ └── index.ts │ ├── CategoryInput │ │ └── index.ts │ ├── LogoUploader │ │ ├── index.ts │ │ └── LogoUploader.tsx │ ├── ToolCardList │ │ ├── index.ts │ │ └── ToolCardList.tsx │ ├── BlurBackground │ │ ├── index.ts │ │ └── BlurBackground.tsx │ ├── CommandPalette │ │ ├── index.ts │ │ ├── EmptyState.tsx │ │ └── SearchItem.tsx │ ├── SelectmenuDate │ │ ├── index.ts │ │ └── SelectmenuDate.tsx │ ├── TabsLink │ │ ├── index.ts │ │ └── Tabs.tsx │ ├── ToolCardEffect │ │ ├── index.ts │ │ └── ToolCardEffect.tsx │ ├── UserProfileInfo │ │ ├── index.ts │ │ └── UserProfileInfo.tsx │ ├── TagsGroup │ │ ├── index.ts │ │ ├── TagsGroup.tsx │ │ └── Tag.tsx │ ├── FormLaunch │ │ ├── index.tsx │ │ ├── FormLaunchWrapper.tsx │ │ └── FormLaunchSection.tsx │ ├── ImagesUploader │ │ ├── index.ts │ │ ├── ImageUploaderItem.tsx │ │ └── ImagesUploader.tsx │ ├── Stats │ │ ├── index.ts │ │ ├── Stat.tsx │ │ ├── Stats.Wrapper.tsx │ │ ├── Stat.CountItem.tsx │ │ └── Stat.Item.tsx │ ├── Gallery │ │ ├── index.ts │ │ ├── VideoThumbnail.tsx │ │ ├── GalleryImage.tsx │ │ └── ButtonHandler.tsx │ ├── Comment │ │ ├── Comment.Deleted.tsx │ │ ├── Comment.Date.tsx │ │ ├── CommentFrom.Wrapper.tsx │ │ ├── Comment.Context.tsx │ │ ├── Comment.UserName.tsx │ │ ├── Comments.tsx │ │ ├── Comment.Form.tsx │ │ ├── index.ts │ │ ├── Comment.tsx │ │ ├── Comment.Textarea.tsx │ │ ├── Comment.UserAvatar.tsx │ │ ├── Comment.Like.tsx │ │ └── Comment.ActionMenu.tsx │ ├── ToolCard │ │ ├── Tool.Title.tsx │ │ ├── Tool.Footer.tsx │ │ ├── Tool.views.tsx │ │ ├── Tool.Tags.tsx │ │ ├── Tool.Logo.tsx │ │ ├── Tool.Name.tsx │ │ ├── ToolCardLink.tsx │ │ └── ToolCard.tsx │ ├── HighlightCode │ │ └── index.tsx │ ├── ProfileFormModal │ │ └── index.tsx │ ├── ModalBannerCode │ │ └── ModalBannerCodeClient.tsx │ ├── Client │ │ ├── CommentsSection.tsx │ │ ├── CommentSection.tsx │ │ └── CommentFormSection.tsx │ ├── ProductHuntCard │ │ └── index.tsx │ ├── PaymentForm.tsx │ ├── Blog │ │ ├── Pagination.tsx │ │ └── ArticleCard.tsx │ ├── AuthProviderButtons │ │ └── index.tsx │ ├── Skeletons │ │ └── SkeletonToolCard.tsx │ ├── ChatWindow │ │ └── index.tsx │ ├── Alert │ │ └── index.tsx │ ├── WinnerBadge │ │ └── index.tsx │ ├── Modal │ │ └── index.tsx │ ├── MonitizerAdCards │ │ └── index.tsx │ ├── LoginPage │ │ └── index.tsx │ ├── SelectLaunchDate │ │ └── index.tsx │ ├── ToolViewModal │ │ └── TrendingToolsList.tsx │ └── TrendingToolsList │ │ └── index.tsx ├── PaymentFormScript.tsx ├── Icons │ ├── IconPlay.tsx │ ├── IconPlus.tsx │ ├── IconChevronLeft.tsx │ ├── IconChevronRight.tsx │ ├── IconArrowLongRight.tsx │ ├── IconXmark.tsx │ ├── IconCodeBracket.tsx │ ├── IconSearch.tsx │ ├── IconArrowLongLeft.tsx │ ├── IconClipboard.tsx │ ├── IconEllipsisVertical.tsx │ ├── IconInformationCircle.tsx │ ├── IconEye.tsx │ ├── IconLoading.tsx │ ├── IconChatBubbleOvalLeftEllipsis.tsx │ ├── IconHeart.tsx │ ├── IconPencilSquare.tsx │ ├── IconChatBubbleLeft.tsx │ ├── IconPhoto.tsx │ ├── IconChartBar.tsx │ ├── IconFire.tsx │ ├── IconTrash.tsx │ ├── IconArrowTopRight.tsx │ ├── IconGlobeAlt.tsx │ ├── IconGoogle.tsx │ ├── index.ts │ ├── IconCalendar.tsx │ ├── IconVote.tsx │ └── IconNewsletterEnvolpe.tsx ├── Protectedroute.tsx ├── supabase │ ├── provider.tsx │ └── listener.tsx └── CodeBlock.tsx ├── public ├── 6f2ec52fc3a4faced95247e7e7230602.txt ├── devhuntog.png ├── johnrush.jpeg ├── devhuntog-1.png ├── vercel.svg ├── next.svg └── user.svg ├── app ├── favicon.ico ├── robots.txt ├── api │ ├── test │ │ └── route.ts │ ├── newsletter │ │ └── route.ts │ ├── login │ │ └── route.ts │ └── ph-dev-tools │ │ ├── route.ts │ │ ├── [slug] │ │ └── route.ts │ │ └── get-website-url │ │ └── [url] │ │ └── route.ts ├── login │ └── page.tsx ├── account │ ├── layout.tsx │ └── tools │ │ └── edit │ │ └── layout.tsx ├── auth │ └── callback │ │ └── route.ts ├── blog │ ├── sitemap.xml │ │ └── route.tsx │ ├── page.tsx │ ├── tag │ │ └── [slug] │ │ │ └── page.tsx │ └── category │ │ └── [slug] │ │ └── page.tsx ├── globals.css ├── all-dev-tools │ └── page.tsx ├── oss-friends │ └── page.tsx ├── the-story │ └── stats.jsx ├── prismjs-theme.css ├── sitemap.xml │ └── route.tsx ├── upcoming │ └── page.tsx └── tools │ └── [slug] │ └── page.tsx ├── postcss.config.js ├── utils ├── mergeTW.ts ├── supabase │ ├── services │ │ ├── BaseDbService.ts │ │ ├── supabaseClient.ts │ │ ├── pricing-types.ts │ │ ├── CacheService.ts │ │ ├── users.ts │ │ ├── upvoteCommenLogs.ts │ │ ├── categories.ts │ │ ├── api.ts │ │ └── awards.ts │ ├── server.ts │ ├── browser.ts │ ├── CustomTypes.ts │ └── fileUploader.ts ├── validateURL.ts ├── createSlug.ts ├── usermaven │ └── index.ts ├── extractVideoId.ts ├── handleURLQuery.tsx ├── sendWelcomeEmail.ts ├── customDateFromNow.ts ├── addHttpsToUrl.ts ├── helpers.ts └── categories.ts ├── .prettierignore ├── type.ts ├── devhunt.code-workspace ├── .prettierrc ├── pages └── api │ ├── auth-token.ts │ ├── api-formatters.ts │ ├── past-week-tools.ts │ ├── week-tools.ts │ └── chat-gpt.ts ├── .gitignore ├── tsconfig.json ├── middleware.ts ├── .eslintrc.json ├── LICENSE ├── tailwind.config.js ├── next.config.js ├── CONTRIBUTING.md └── package.json /supabase/.gitignore: -------------------------------------------------------------------------------- 1 | # Supabase 2 | .branches 3 | .temp 4 | -------------------------------------------------------------------------------- /components/ui/Avatar/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Avatar' 2 | -------------------------------------------------------------------------------- /components/ui/Brand/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Brand' 2 | -------------------------------------------------------------------------------- /components/ui/Button/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Button' 2 | -------------------------------------------------------------------------------- /components/ui/Footer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Footer' 2 | -------------------------------------------------------------------------------- /components/ui/Input/index.tsx: -------------------------------------------------------------------------------- 1 | export { default } from './Input' 2 | -------------------------------------------------------------------------------- /components/ui/Label/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Label' 2 | -------------------------------------------------------------------------------- /components/ui/Link/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './LinkItem' 2 | -------------------------------------------------------------------------------- /components/ui/Navbar/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Navbar' 2 | -------------------------------------------------------------------------------- /components/ui/Radio/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Radio' 2 | -------------------------------------------------------------------------------- /components/ui/Banner/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Banner'; 2 | -------------------------------------------------------------------------------- /components/ui/Checkbox/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Checkbox' 2 | -------------------------------------------------------------------------------- /components/ui/Page404/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Page404' 2 | -------------------------------------------------------------------------------- /components/ui/Textarea/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Textarea' 2 | -------------------------------------------------------------------------------- /components/ui/UploadAvatar/index.ts: -------------------------------------------------------------------------------- 1 | export {default} from "./UploadAvatar" -------------------------------------------------------------------------------- /components/ui/AvatarMenu/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './AvatarMenu' 2 | -------------------------------------------------------------------------------- /components/ui/LabelError/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './LabelError' 2 | -------------------------------------------------------------------------------- /components/ui/LinkShiny/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './LinkShiny' 2 | -------------------------------------------------------------------------------- /public/6f2ec52fc3a4faced95247e7e7230602.txt: -------------------------------------------------------------------------------- 1 | 6f2ec52fc3a4faced95247e7e7230602 -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarsX-dev/devhunt/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /components/ui/ButtonUpvote/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './ButtonUpvote' 2 | -------------------------------------------------------------------------------- /components/ui/CategoryInput/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './CategoryInput' 2 | -------------------------------------------------------------------------------- /components/ui/LogoUploader/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './LogoUploader'; 2 | -------------------------------------------------------------------------------- /components/ui/ToolCardList/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './ToolCardList' 2 | -------------------------------------------------------------------------------- /components/ui/BlurBackground/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './BlurBackground' 2 | -------------------------------------------------------------------------------- /components/ui/CommandPalette/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './CommandPalette' 2 | -------------------------------------------------------------------------------- /components/ui/SelectmenuDate/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './SelectmenuDate'; 2 | -------------------------------------------------------------------------------- /components/ui/TabsLink/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Tabs' 2 | export * from './TabLink' 3 | -------------------------------------------------------------------------------- /components/ui/ToolCardEffect/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './ToolCardEffect'; 2 | -------------------------------------------------------------------------------- /components/ui/UserProfileInfo/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './UserProfileInfo' 2 | -------------------------------------------------------------------------------- /components/ui/TagsGroup/index.ts: -------------------------------------------------------------------------------- 1 | export * from './TagsGroup' 2 | export * from './Tag' 3 | -------------------------------------------------------------------------------- /public/devhuntog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarsX-dev/devhunt/HEAD/public/devhuntog.png -------------------------------------------------------------------------------- /public/johnrush.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarsX-dev/devhunt/HEAD/public/johnrush.jpeg -------------------------------------------------------------------------------- /public/devhuntog-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarsX-dev/devhunt/HEAD/public/devhuntog-1.png -------------------------------------------------------------------------------- /app/robots.txt: -------------------------------------------------------------------------------- 1 | User-Agent: * 2 | Allow: / 3 | Disallow: /private/ 4 | Sitemap: https://devhunt.org/sitemap.xml -------------------------------------------------------------------------------- /components/ui/FormLaunch/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './FormLaunchSection' 2 | export * from './FormLaunchWrapper' 3 | -------------------------------------------------------------------------------- /components/ui/ImagesUploader/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ImagesUploader' 2 | export * from './ImageUploaderItem' 3 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /utils/mergeTW.ts: -------------------------------------------------------------------------------- 1 | import { twMerge } from 'tailwind-merge'; 2 | 3 | export default (...ClassNameValue: string[]) => twMerge(ClassNameValue); 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .serverless 2 | __generated__ 3 | CHANGELOG.md 4 | coverage 5 | dist 6 | pnpm-lock.yaml 7 | prisma/migrations 8 | **/translations/*.json 9 | -------------------------------------------------------------------------------- /components/ui/Stats/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Stats.Wrapper' 2 | export * from './Stat.Item' 3 | export * from './Stat.CountItem' 4 | export * from './Stat' 5 | -------------------------------------------------------------------------------- /components/ui/Gallery/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Gallery'; 2 | export * from './GalleryImage'; 3 | export * from './ButtonHandler'; 4 | export * from './VideoThumbnail'; 5 | -------------------------------------------------------------------------------- /app/api/test/route.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { NextResponse } from 'next/server'; 3 | 4 | export async function GET() { 5 | return NextResponse.json({ data: 'We are testing something out' }); 6 | } 7 | -------------------------------------------------------------------------------- /app/login/page.tsx: -------------------------------------------------------------------------------- 1 | import LoginPage from '@/components/ui/LoginPage'; 2 | 3 | export const metadata = { 4 | title: 'Login to your account', 5 | }; 6 | 7 | export default function Login() { 8 | return ; 9 | } 10 | -------------------------------------------------------------------------------- /type.ts: -------------------------------------------------------------------------------- 1 | import { Product } from './utils/supabase/types'; 2 | 3 | export interface ProductType extends Product { 4 | product_pricing_types: { 5 | title: string; 6 | }; 7 | product_categories: { 8 | name: string; 9 | }[]; 10 | } 11 | -------------------------------------------------------------------------------- /components/ui/Comment/Comment.Deleted.tsx: -------------------------------------------------------------------------------- 1 | export const CommentDeleted = () => ( 2 |
3 | This comment has been deleted. 4 |
5 | ) 6 | -------------------------------------------------------------------------------- /utils/supabase/services/BaseDbService.ts: -------------------------------------------------------------------------------- 1 | import { type SupabaseClient } from '@supabase/supabase-js' 2 | import { type Database } from '../types' 3 | 4 | export default abstract class BaseDbService { 5 | constructor (public supabase: SupabaseClient) {} 6 | } 7 | -------------------------------------------------------------------------------- /utils/validateURL.ts: -------------------------------------------------------------------------------- 1 | export default function validateURL(url: string) { 2 | // Regular expression pattern for URL validation 3 | var pattern = /^(https?:\/\/)?([a-z0-9-]+\.)+[a-z]{2,}(\/.*)*$/i 4 | 5 | // Test the URL against the pattern 6 | return pattern.test(url) 7 | } 8 | -------------------------------------------------------------------------------- /components/ui/ToolCard/Tool.Title.tsx: -------------------------------------------------------------------------------- 1 | import mergeTW from '@/utils/mergeTW'; 2 | import { ReactNode } from 'react'; 3 | 4 | export default ({ className, children }: { className?: string; children?: ReactNode }) => ( 5 |

{children}

6 | ); 7 | -------------------------------------------------------------------------------- /components/ui/Comment/Comment.Date.tsx: -------------------------------------------------------------------------------- 1 | import mergeTW from '@/utils/mergeTW' 2 | import { ReactNode } from 'react' 3 | 4 | export const CommentDate = ({ className, children }: { className?: string; children?: ReactNode }) => ( 5 | {children} 6 | ) 7 | -------------------------------------------------------------------------------- /components/ui/LabelError/LabelError.tsx: -------------------------------------------------------------------------------- 1 | import mergeTW from '@/utils/mergeTW' 2 | import { ReactNode } from 'react' 3 | 4 | export default ({ className, children }: { className?: string; children?: ReactNode }) => ( 5 | {children} 6 | ) 7 | -------------------------------------------------------------------------------- /components/ui/Stats/Stat.tsx: -------------------------------------------------------------------------------- 1 | import mergeTW from '@/utils/mergeTW' 2 | import { type ReactNode } from 'react' 3 | 4 | export const Stat = ({ children, className }: { children: ReactNode; className?: string }) => ( 5 |
  • {children}
  • 6 | ) 7 | -------------------------------------------------------------------------------- /components/ui/ToolCard/Tool.Footer.tsx: -------------------------------------------------------------------------------- 1 | import mergeTW from '@/utils/mergeTW'; 2 | import { ReactNode } from 'react'; 3 | 4 | export default ({ className, children }: { className?: string; children?: ReactNode }) => ( 5 |
    {children}
    6 | ); 7 | -------------------------------------------------------------------------------- /components/ui/TagsGroup/TagsGroup.tsx: -------------------------------------------------------------------------------- 1 | import mergeTW from '@/utils/mergeTW' 2 | import { ReactNode } from 'react' 3 | 4 | export const TagsGroup = ({ children, className = '' }: { children: ReactNode; className?: string }) => ( 5 | 6 | ) 7 | -------------------------------------------------------------------------------- /components/ui/Comment/CommentFrom.Wrapper.tsx: -------------------------------------------------------------------------------- 1 | import mergeTW from '@/utils/mergeTW' 2 | import { ReactNode } from 'react' 3 | 4 | export const CommentFormWrapper = ({ children, className }: { children: ReactNode; className?: string }) => ( 5 |
    {children}
    6 | ) 7 | -------------------------------------------------------------------------------- /components/ui/HighlightCode/index.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useEffect } from 'react'; 4 | import hljs from 'highlight.js'; 5 | import 'highlight.js/styles/vs2015.min.css'; 6 | 7 | export default function HighlightCode() { 8 | useEffect(() => { 9 | hljs.highlightAll(); 10 | }, []); 11 | return null; 12 | } 13 | -------------------------------------------------------------------------------- /components/ui/Stats/Stats.Wrapper.tsx: -------------------------------------------------------------------------------- 1 | import mergeTW from '@/utils/mergeTW' 2 | import { type ReactNode } from 'react' 3 | 4 | export const StatsWrapper = ({ children, className }: { children: ReactNode; className?: string }) => ( 5 | 6 | ) 7 | -------------------------------------------------------------------------------- /utils/supabase/services/supabaseClient.ts: -------------------------------------------------------------------------------- 1 | import { createClient } from '@supabase/supabase-js'; 2 | 3 | export const supabase = createClient(process.env.NEXT_PUBLIC_SUPABASE_URL as string, process.env.SUPABASE_SERVICE_ROLE_KEY as string, { 4 | auth: { 5 | autoRefreshToken: false, 6 | persistSession: false, 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /components/ui/Comment/Comment.Context.tsx: -------------------------------------------------------------------------------- 1 | import mergeTW from '@/utils/mergeTW' 2 | import { ReactNode } from 'react' 3 | 4 | export const CommentContext = ({ className, children }: { className?: string; children?: ReactNode }) => ( 5 |

    {children}

    6 | ) 7 | -------------------------------------------------------------------------------- /components/ui/Stats/Stat.CountItem.tsx: -------------------------------------------------------------------------------- 1 | import mergeTW from '@/utils/mergeTW' 2 | import { type ReactNode } from 'react' 3 | 4 | export const StatCountItem = ({ children, className }: { children: ReactNode; className?: string }) => ( 5 | {children} 6 | ) 7 | -------------------------------------------------------------------------------- /components/ui/Stats/Stat.Item.tsx: -------------------------------------------------------------------------------- 1 | import mergeTW from '@/utils/mergeTW' 2 | import { type ReactNode } from 'react' 3 | 4 | export const StatItem = ({ children, className }: { children: ReactNode; className?: string }) => ( 5 |
    {children}
    6 | ) 7 | -------------------------------------------------------------------------------- /components/ui/Comment/Comment.UserName.tsx: -------------------------------------------------------------------------------- 1 | import mergeTW from '@/utils/mergeTW' 2 | import { ReactNode } from 'react' 3 | 4 | export const CommentUserName = ({ className, children }: { className?: string; children?: ReactNode }) => ( 5 | {children} 6 | ) 7 | -------------------------------------------------------------------------------- /components/ui/Comment/Comments.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { HTMLAttributes, ReactNode, useEffect } from 'react' 4 | 5 | interface Props extends HTMLAttributes { 6 | children: ReactNode 7 | } 8 | 9 | export const Comments = ({ children, ...props }: Props) => { 10 | return
      {children}
    11 | } 12 | -------------------------------------------------------------------------------- /devhunt.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "name": "project-root", 5 | "path": "./" 6 | }, 7 | { 8 | "name": "supabase-functions", 9 | "path": "supabase/functions" 10 | } 11 | ], 12 | "settings": { 13 | "files.exclude": { 14 | "supabase/functions/": true 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /utils/supabase/server.ts: -------------------------------------------------------------------------------- 1 | import { cookies } from 'next/headers'; 2 | import { type SupabaseClient, createServerComponentClient } from '@supabase/auth-helpers-nextjs'; 3 | import { type Database } from '@/utils/supabase/types'; 4 | 5 | export const createServerClient = (): SupabaseClient => 6 | createServerComponentClient({ cookies }); 7 | -------------------------------------------------------------------------------- /utils/createSlug.ts: -------------------------------------------------------------------------------- 1 | export default (title: string) => { 2 | const lowercaseTitle = title.toLowerCase(); 3 | const slug = lowercaseTitle 4 | .replace(/\s+/g, '-') // Replace spaces with hyphens 5 | .replace(/[^a-z0-9-]/g, '') // Remove non-alphanumeric characters (excluding hyphens) 6 | .replace(/-{2,}/g, '-'); // Remove multiple consecutive hyphens 7 | return slug; 8 | }; 9 | -------------------------------------------------------------------------------- /utils/usermaven/index.ts: -------------------------------------------------------------------------------- 1 | import { usermavenClient, UsermavenClient } from '@usermaven/sdk-js'; 2 | 3 | let usermaven: UsermavenClient | null = null; 4 | if (process.env.USER_MAVEN_KEY) { 5 | usermaven = usermavenClient({ 6 | key: process.env.USER_MAVEN_KEY as string, 7 | tracking_host: 'https://events.usermaven.com', 8 | }); 9 | } 10 | 11 | export default usermaven; 12 | -------------------------------------------------------------------------------- /components/PaymentFormScript.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import Script from 'next/script'; 3 | import { usePathname } from 'next/navigation'; 4 | 5 | export default () => { 6 | const pathname = usePathname(); 7 | return pathname?.includes('/account/tools/activate-launch') ? ( 8 |