diff --git a/app/api/route.ts b/app/api/route.ts new file mode 100644 index 000000000..4a475dd3a --- /dev/null +++ b/app/api/route.ts @@ -0,0 +1,54 @@ +import admin from 'firebase-admin'; +import { promises as fs } from 'fs'; +import path from 'path'; +import { NextResponse } from 'next/server'; +import { customInitApp } from 'lib/firebase-admin-config'; + +customInitApp(); + +const folders = [ + 'BlockChain', + 'DSA', + 'artificial_intelligence', + 'backend', + 'cloud_computing_platforms', + 'competitive_programming', + 'cybersecurity', + 'data_structures', + 'devops', + 'frontend', + 'internet_of_things', + 'languages', + 'open_source', + 'other', + 'placement_prep', + 'resources', + 'technical-writing', + 'youtube' +]; + +export async function GET() { + try { + const firestore = admin.firestore(); + const mainDirectoryPath = path.join(__dirname, '../../../../database'); + for (let i = 0; i < folders.length; i++) { + const folder = folders[i]; + const folderPath = path.join(mainDirectoryPath, folder); + + const files = await fs.readdir(folderPath); + for (let j = 0; j < files.length; j++) { + const file = files[j]; + const filePath = path.join(folderPath, file); + + const fileContent = await fs.readFile(filePath, 'utf-8'); + const jsonData = JSON.parse(fileContent); + console.log(jsonData); + firestore.collection('resources').doc(folder).set({ resources: jsonData }); + } + } + return NextResponse.json({ message: 'Imported to Firestore' }); + } catch (error) { + console.error('Error occurred: \n', error); + return NextResponse.json({ message: 'Error occurred' }); + } +} diff --git a/components/Cards/Card.tsx b/components/Cards/Card.tsx index 726fc07a7..3fa3813b0 100644 --- a/components/Cards/Card.tsx +++ b/components/Cards/Card.tsx @@ -4,6 +4,19 @@ import { AiOutlineRead } from 'react-icons/ai' import { HiOutlineExternalLink } from 'react-icons/hi' import { CopyToClipboard } from 'components/CopyToClipboard/CopyToClipboard' import type { IData } from 'types' +import { + collection, + doc, + where, + query, + getDocs, + setDoc, + getDoc, +} from 'firebase/firestore' +import { db } from '../../lib/firebase-config' +import { Timestamp } from 'firebase/firestore' +import Image from 'next/image' + import Bookmark from 'components/Bookmark/Bookmark' interface CardProps { @@ -16,6 +29,92 @@ export const Card: FC = ({ data, onClick }) => { const descriptionRef = useRef(null) const [isOverflow, setIsOverflow] = useState(false) const youtubeRegex = /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/.+$/ + const id = data.url.replace(/[^\w\s]/gi, '') + + const [upvoteCount, setUpvoteCount] = useState(0) + const [isUpvoted, setIsUpvoted] = useState(false) + const timestamp = Timestamp.fromDate(new Date()) + const date = timestamp.toDate() + const user = { + name: 'Vidip', + uid: 1234, + } + const docRef = doc(db, 'resources', id) + const save = async () => { + await setDoc( + docRef, + { + name: name, + }, + { merge: true } + ) + } + + const addUserToAssetBookmark = async () => { + try { + const subcollectionRef = collection(db, 'resources') + const assetQuery = query(subcollectionRef, where('name', '==', data.name)) + const assetQuerySnapshot = await getDocs(assetQuery) + console.log('Asset Query: ', assetQuery) + console.log('Asset Query Snapshot: ', assetQuerySnapshot) + if (assetQuerySnapshot.empty) { + console.log('Asset not found') + return + } + + const assetDocSnapshot = assetQuerySnapshot.docs[0] + const assetDocRef = doc(db, 'resources', data.name) + const assetData = assetDocSnapshot.data() + console.log('Asset Data: ', assetData) + + const upvotes = assetData.upvotes || {} + const userUid = user.uid + + if (upvotes[userUid]) { + // User has already upvoted, so remove their upvote + delete upvotes[userUid] + } else { + // User has not upvoted, so add their upvote + upvotes[userUid] = true + } + await setDoc(assetDocRef, { + name: name, + description: description, + url: url, + upvotedBy: user, + created: date, // Keep existing data + upvotes: upvotes, + }) + + const updatedAssetDoc = await getDoc(assetDocRef) + if (!updatedAssetDoc.exists()) { + console.log('Asset document not found') + return + } + const updatedUpvotes = updatedAssetDoc.data().upvotes || {} + const upvoteCount = Object.keys(updatedUpvotes).length + setUpvoteCount(upvoteCount) + console.log(upvoteCount) + } catch (error) { + console.error('Error adding user to asset upvotes:', error) + } + } + + const toggleUpvote = () => { + setIsUpvoted((p) => !p) + } + + const handleClick = async (e: React.MouseEvent) => { + e.stopPropagation() + e.preventDefault() + toggleUpvote() + save() + await addUserToAssetBookmark() + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const Img = ({ url }: any) => { + return {'altimage'} + } useEffect(() => { if (descriptionRef.current) { @@ -25,7 +124,6 @@ export const Card: FC = ({ data, onClick }) => { ) } }, []) - return (
@@ -56,8 +154,16 @@ export const Card: FC = ({ data, onClick }) => { )}
+
+

{upvoteCount}

+ +