feat: add payments feature access based on config

This commit is contained in:
swve 2024-11-25 23:56:08 +01:00
parent 5a746a946d
commit 546e8a5f98
19 changed files with 98 additions and 43 deletions

View file

@ -11,11 +11,13 @@ import UserAvatar from '../../Objects/UserAvatar'
import AdminAuthorization from '@components/Security/AdminAuthorization'
import { useLHSession } from '@components/Contexts/LHSessionContext'
import { getUriWithOrg, getUriWithoutOrg } from '@services/config/config'
import useFeatureFlag from '@components/Hooks/useFeatureFlag'
function DashLeftMenu() {
const org = useOrg() as any
const session = useLHSession() as any
const [loading, setLoading] = React.useState(true)
const isPaymentsEnabled = useFeatureFlag({ path: ['features', 'payments', 'enabled'], defaultValue: false })
function waitForEverythingToLoad() {
if (org && session) {
@ -112,14 +114,16 @@ function DashLeftMenu() {
<Users size={18} />
</Link>
</ToolTip>
<ToolTip content={'Payments'} slateBlack sideOffset={8} side="right">
<Link
className="bg-white/5 rounded-lg p-2 hover:bg-white/10 transition-all ease-linear"
href={`/dash/payments/customers`}
>
<BadgeDollarSign size={18} />
</Link>
</ToolTip>
{isPaymentsEnabled && (
<ToolTip content={'Payments'} slateBlack sideOffset={8} side="right">
<Link
className="bg-white/5 rounded-lg p-2 hover:bg-white/10 transition-all ease-linear"
href={`/dash/payments/customers`}
>
<BadgeDollarSign size={18} />
</Link>
</ToolTip>
)}
<ToolTip
content={'Organization'}
slateBlack

View file

@ -12,7 +12,7 @@ import { useRouter } from 'next/navigation'
import { useOrg } from '@components/Contexts/OrgContext'
import { useLHSession } from '@components/Contexts/LHSessionContext'
import { getOrgLogoMediaDirectory, getOrgThumbnailMediaDirectory } from '@services/media/media'
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@components/Ui/tabs"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@components/ui/tabs"
import { Toaster, toast } from 'react-hot-toast';
import { constructAcceptValue } from '@/lib/constants';

View file

@ -10,8 +10,8 @@ import toast from 'react-hot-toast';
import useSWR, { mutate } from 'swr';
import Modal from '@components/Objects/StyledElements/Modal/Modal';
import ConfirmationModal from '@components/Objects/StyledElements/ConfirmationModal/ConfirmationModal';
import { Button } from '@components/Ui/button';
import { Alert, AlertDescription, AlertTitle } from '@components/Ui/alert';
import { Button } from '@components/ui/button';
import { Alert, AlertDescription, AlertTitle } from '@components/ui/alert';
import { useRouter } from 'next/navigation';
import { getUriWithoutOrg } from '@services/config/config';

View file

@ -9,9 +9,9 @@ import {
TableHead,
TableHeader,
TableRow,
} from "@components/Ui/table"
} from "@components/ui/table"
import { getOrgCustomers } from '@services/payments/payments'
import { Badge } from '@components/Ui/badge'
import { Badge } from '@components/ui/badge'
import PageLoading from '@components/Objects/Loaders/PageLoading'
import { RefreshCcw, SquareCheck } from 'lucide-react'
import { getUserAvatarMediaDirectory } from '@services/media/media'

View file

@ -9,14 +9,14 @@ import { Plus, Pencil, Info, RefreshCcw, SquareCheck, ChevronDown, ChevronUp, Ar
import Modal from '@components/Objects/StyledElements/Modal/Modal';
import ConfirmationModal from '@components/Objects/StyledElements/ConfirmationModal/ConfirmationModal';
import toast from 'react-hot-toast';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@components/Ui/select"
import { Button } from "@components/Ui/button"
import { Input } from "@components/Ui/input"
import { Textarea } from "@components/Ui/textarea"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@components/ui/select"
import { Button } from "@components/ui/button"
import { Input } from "@components/ui/input"
import { Textarea } from "@components/ui/textarea"
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
import { Label } from '@components/Ui/label';
import { Badge } from '@components/Ui/badge';
import { Label } from '@components/ui/label';
import { Badge } from '@components/ui/badge';
import { getPaymentConfigs } from '@services/payments/payments';
import ProductLinkedCourses from './SubComponents/ProductLinkedCourses';
import { usePaymentsEnabled } from '@hooks/usePaymentsEnabled';

View file

@ -6,11 +6,11 @@ import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
import toast from 'react-hot-toast';
import { mutate } from 'swr';
import { Button } from "@components/Ui/button";
import { Input } from "@components/Ui/input";
import { Textarea } from "@components/Ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@components/Ui/select";
import { Label } from "@components/Ui/label";
import { Button } from "@components/ui/button";
import { Input } from "@components/ui/input";
import { Textarea } from "@components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@components/ui/select";
import { Label } from "@components/ui/label";
import currencyCodes from 'currency-codes';
const validationSchema = Yup.object().shape({

View file

@ -2,8 +2,8 @@ import React, { useState } from 'react';
import { useOrg } from '@components/Contexts/OrgContext';
import { useLHSession } from '@components/Contexts/LHSessionContext';
import { linkCourseToProduct } from '@services/payments/products';
import { Button } from "@components/Ui/button";
import { Input } from "@components/Ui/input";
import { Button } from "@components/ui/button";
import { Input } from "@components/ui/input";
import { Search } from 'lucide-react';
import toast from 'react-hot-toast';
import { mutate } from 'swr';

View file

@ -3,7 +3,7 @@ import { getCoursesLinkedToProduct, unlinkCourseFromProduct } from '@services/pa
import { useLHSession } from '@components/Contexts/LHSessionContext';
import { useOrg } from '@components/Contexts/OrgContext';
import { Trash2, Plus, BookOpen } from 'lucide-react';
import { Button } from "@components/Ui/button";
import { Button } from "@components/ui/button";
import toast from 'react-hot-toast';
import { mutate } from 'swr';
import Modal from '@components/Objects/StyledElements/Modal/Modal';

View file

@ -0,0 +1,36 @@
import { useOrg } from '@components/Contexts/OrgContext'
import { useEffect, useState } from 'react'
type FeatureType = {
path: string[]
defaultValue?: boolean
}
function useFeatureFlag(feature: FeatureType) {
const org = useOrg() as any
const [isEnabled, setIsEnabled] = useState<boolean>(!!feature.defaultValue)
useEffect(() => {
if (org?.config?.config) {
let currentValue = org.config.config
// Traverse the path to get the feature flag value
for (const key of feature.path) {
if (currentValue && typeof currentValue === 'object') {
currentValue = currentValue[key]
} else {
currentValue = feature.defaultValue || false
break
}
}
setIsEnabled(!!currentValue)
} else {
setIsEnabled(!!feature.defaultValue)
}
}, [org, feature])
return isEnabled
}
export default useFeatureFlag

View file

@ -4,8 +4,8 @@ import { useLHSession } from '@components/Contexts/LHSessionContext'
import useSWR from 'swr'
import { getProductsByCourse, getStripeProductCheckoutSession } from '@services/payments/products'
import { RefreshCcw, SquareCheck, ChevronDown, ChevronUp } from 'lucide-react'
import { Badge } from '@components/Ui/badge'
import { Button } from '@components/Ui/button'
import { Badge } from '@components/ui/badge'
import { Button } from '@components/ui/button'
import toast from 'react-hot-toast'
import { useRouter } from 'next/navigation'
import { getUriWithOrg } from '@services/config/config'

View file

@ -1,7 +1,7 @@
'use client'
import { Input } from "@components/Ui/input"
import { Textarea } from "@components/Ui/textarea"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@components/Ui/select"
import { Input } from "@components/ui/input"
import { Textarea } from "@components/ui/textarea"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@components/ui/select"
import FormLayout, {
FormField,
FormLabelAndMessage,

View file

@ -1,7 +1,7 @@
'use client'
import React from 'react'
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, DialogFooter } from "@components/Ui/dialog"
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, DialogFooter } from "@components/ui/dialog"
import { ButtonBlack } from '../Form/Form'
import { cn } from "@/lib/utils"

View file

@ -17,7 +17,7 @@ import {
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@components/Ui/dropdown-menu"
} from "@components/ui/dropdown-menu"
type Course = {
course_uuid: string

View file

@ -1,5 +1,5 @@
import { Settings, ChevronRight, CreditCard } from 'lucide-react'
import { Alert, AlertTitle, AlertDescription } from '@components/Ui/alert'
import { Alert, AlertTitle, AlertDescription } from '@components/ui/alert'
import { AlertTriangle, ShoppingCart, Users } from 'lucide-react'
import React from 'react'
import Link from 'next/link'

View file

@ -5,7 +5,7 @@ import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
import { type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { toggleVariants } from "@components/Ui/toggle"
import { toggleVariants } from "@components/ui/toggle"
const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants>