diff --git a/.env.example b/.env.example index 7979acac4..476761729 100644 --- a/.env.example +++ b/.env.example @@ -15,6 +15,6 @@ BOT_TOKEN = "123" GUILD_ID = "123" LOCAL_CMS_PROVIDER = true CACHE_EXPIRE_S = 10 - ADMINS = "Random,example@gmail.com" NEXT_PUBLIC_DISABLE_FEATURES = "featurea,featureb,featurec" +NEXT_PUBLIC_DISCORD_WEBHOOK_URL="" \ No newline at end of file diff --git a/README.md b/README.md index f45afa4ad..362ad53a1 100644 --- a/README.md +++ b/README.md @@ -92,4 +92,12 @@ Read our [contribution guidelines](./CONTRIBUTING.md) for more details. ## Issues on mac Silicon -brew install pkg-config cairo pango libpng jpeg giflib librsvg \ No newline at end of file +brew install pkg-config cairo pango libpng jpeg giflib librsvg + + + +## Discord Webhook Configuration + +![image](https://github.com/code100x/bounty-hook/assets/118182376/6653f928-95e0-4f55-8da8-b15837c9e66f) +![image](https://github.com/code100x/bounty-hook/assets/118182376/e504b067-ba88-4a91-8947-7433d5a75419) +![image](https://github.com/code100x/bounty-hook/assets/118182376/19c1db48-cefc-46d7-964c-ca5e39c94d80) \ No newline at end of file diff --git a/package.json b/package.json index 8bb3a0e51..a9fad2fb5 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-navigation-menu": "^1.1.4", diff --git a/src/app/admin/content/[...courseId]/page.tsx b/src/app/admin/content/[...courseId]/page.tsx index 5d9cef4f6..ce76cabce 100644 --- a/src/app/admin/content/[...courseId]/page.tsx +++ b/src/app/admin/content/[...courseId]/page.tsx @@ -46,8 +46,10 @@ export default async function UpdateCourseContent({ {course?.title}
Content
({ diff --git a/src/app/api/admin/content/route.ts b/src/app/api/admin/content/route.ts index 7f7c6a1f3..d43a12599 100644 --- a/src/app/api/admin/content/route.ts +++ b/src/app/api/admin/content/route.ts @@ -103,5 +103,5 @@ export const POST = async (req: NextRequest) => { }); } } - return NextResponse.json({}, { status: 200 }); + return NextResponse.json({ id: content.id }, { status: 200 }); }; diff --git a/src/app/services/DiscordService.tsx b/src/app/services/DiscordService.tsx new file mode 100644 index 000000000..b52d51c22 --- /dev/null +++ b/src/app/services/DiscordService.tsx @@ -0,0 +1,40 @@ +import axios from 'axios'; + +interface DiscordData { + type: string; + thumbnail: string; + title: string; + courseTitle: string; + courseId: number; + mediaId: number; + currFolderId: number; +} + +export default function DiscordService() { + const sendUpdateToDiscord = async (data: DiscordData) => { + const body = { + content: 'Hello @everyone', + tts: false, + color: 'white', + embeds: [ + { + title: `New ${data?.type === 'notion' ? 'NOTE' : data?.type?.toUpperCase()}`, + description: `${data?.title} has been added in the ${data?.courseTitle} , [Click here to visit this ${data?.type === 'notion' ? 'note' : data?.type}](https://app.100xdevs.com/courses/${data.courseId}/${data.currFolderId}/${data.mediaId})`, + }, + ], + }; + + try { + const res = await axios.post( + `${process.env.NEXT_PUBLIC_DISCORD_WEBHOOK_URL}`, + body, + ); + console.log(res); + } catch (error) { + console.log(error); + } + }; + return { + sendUpdateToDiscord, + }; +} diff --git a/src/components/admin/AddContent.tsx b/src/components/admin/AddContent.tsx index 4bdbbe702..2b5435724 100644 --- a/src/components/admin/AddContent.tsx +++ b/src/components/admin/AddContent.tsx @@ -2,19 +2,88 @@ import { useEffect, useState } from 'react'; import { AddNotionMetadata } from './AddNotionMetadata'; import { Input } from '../ui/input'; +import { useRecoilState } from 'recoil'; +import { loader } from '@/store/atoms/loader'; +import DiscordService from '@/app/services/DiscordService'; +import { Checkbox } from '../ui/checkbox'; export const AddContent = ({ + rest, courseId, parentContentId, + courseTitle, }: { + rest: string[]; courseId: number; parentContentId?: number; + courseTitle: string; }) => { const [type, setType] = useState('folder'); const [imageUri, setImageUri] = useState(''); const [title, setTitle] = useState(''); const [metadata, setMetadata] = useState({}); + const [checked, setChecked] = useState(true); const [adminPassword, setAdminPassword] = useState(''); + const [loading, setLoading] = useRecoilState(loader); + + const { sendUpdateToDiscord } = DiscordService(); + + interface DiscordData { + type: string; + thumbnail: string; + title: string; + courseTitle: string; + courseId: number; + currFolderId: number; + mediaId: number; + } + + const postOnDiscord = (data: DiscordData) => { + sendUpdateToDiscord(data); + }; + + const handleContentSubmit = async () => { + setLoading(true); + const response = await fetch('/api/admin/content', { + body: JSON.stringify({ + type, + description: '', + thumbnail: imageUri, + title, + courseId, + parentContentId, + metadata, + adminPassword, + }), + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }); + setLoading(false); + + const respData: { id: number } = await response.json(); + + const data = { + type, + thumbnail: + 'https://d2szwvl7yo497w.cloudfront.net/courseThumbnails/video.png', + title, + courseTitle, + courseId, + currFolderId: parseInt(rest[0], 10), + mediaId: respData.id, + }; + + if (checked && response.status === 200) { + if (type === 'notion' || type === 'video') { + postOnDiscord(data); + setLoading(false); + } + } else { + setLoading(false); + } + }; return (
@@ -22,23 +91,47 @@ export const AddContent = ({
+ {(type === 'video' || type === 'notion') && ( +
+ setChecked((prev) => !prev)} + defaultChecked + id="discord" + /> + +
+ )}

} {type === 'notion' && }
diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx new file mode 100644 index 000000000..216283d6b --- /dev/null +++ b/src/components/ui/checkbox.tsx @@ -0,0 +1,30 @@ +'use client'; + +import * as React from 'react'; +import * as CheckboxPrimitive from '@radix-ui/react-checkbox'; +import { Check } from 'lucide-react'; + +import { cn } from '@/lib/utils'; + +const Checkbox = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + + +)); +Checkbox.displayName = CheckboxPrimitive.Root.displayName; + +export { Checkbox }; diff --git a/src/store/atoms/loader.ts b/src/store/atoms/loader.ts new file mode 100644 index 000000000..83aa57297 --- /dev/null +++ b/src/store/atoms/loader.ts @@ -0,0 +1,6 @@ +import { atom } from 'recoil'; + +export const loader = atom({ + key: 'loader', + default: false, +});