Skip to content

Commit

Permalink
feat: Bookmark feature (#85)
Browse files Browse the repository at this point in the history
* refactor: code refactored for likes count

* fix: image fix and minor bookmark configuration added

* feat: bookmark feature partial dependency

* feat: bookmark feature created
  • Loading branch information
Sanchitbajaj02 authored Dec 14, 2023
1 parent a05f7a6 commit 9d6ba92
Show file tree
Hide file tree
Showing 23 changed files with 526 additions and 123 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"start": "next start",
"lint": "next lint",
"preinstall": "npx only-allow yarn",
"huskyconf": "yarn husky install"
"prepare": "husky install"
},
"husky": {
"hooks": {
Expand Down
Binary file added public/assets/palettegram-for.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/assets/palettegram_for.png
Binary file not shown.
14 changes: 10 additions & 4 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import "@/styles/globals.css";
import { Inter } from "next/font/google";
import { Inter, Poppins } from "next/font/google";
import { Metadata } from "next";
import ReduxProvider from "@/redux/ReduxProvider";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { Providers } from "./providers";

const interFont = Inter({
// const interFont = Inter({
// subsets: ["latin"],
// weight: ["400", "500", "600", "700", "800", "900"],
// variable: "--font-inter",
// });

const poppinsFont = Poppins({
subsets: ["latin"],
weight: ["400", "500", "600", "700", "800", "900"],
variable: "--font-inter",
variable: "--font-poppins",
});

export const metadata: Metadata = {
Expand Down Expand Up @@ -48,7 +54,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
return (
<html lang="en" suppressHydrationWarning>
<body
className={`${interFont.className} scrollbar-thin scrollbar-thumb-primary scrollbar-track-secondary-light scrollbar-track-rounded-full bg-white dark:bg-secondary`}
className={`${poppinsFont.className} scrollbar-thin scrollbar-thumb-primary scrollbar-track-secondary-light scrollbar-track-rounded-full bg-white dark:bg-secondary`}
>
<ToastContainer
position="top-right"
Expand Down
3 changes: 2 additions & 1 deletion src/backend/appwrite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ const storage = new Storage(appwriteClient);
const palettegramDB = String(process.env.NEXT_PUBLIC_DATABASE_ID);
const usersCollection = String(process.env.NEXT_PUBLIC_USER_COLLECTION);
const postsCollection = String(process.env.NEXT_PUBLIC_POSTS_COLLECTION);
const bookmarksCollection = String(process.env.NEXT_PUBLIC_BOOKMARKS_COLLECTION);
const bucketStorage = String(process.env.NEXT_PUBLIC_BUCKET_ID);

export { appwriteClient, account, db, storage, ID, Query };

export { palettegramDB, usersCollection, postsCollection, bucketStorage };
export { palettegramDB, usersCollection, postsCollection, bookmarksCollection, bucketStorage };
36 changes: 30 additions & 6 deletions src/backend/auth.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { account, db, ID, palettegramDB, usersCollection } from "./appwrite.config";

/**
* **Work:** Register the user into the database
* @description Register the user into the database
* @param {Object} userData
* @returns {Object} authResponse
*/
Expand Down Expand Up @@ -48,7 +48,7 @@ const registerUser = async (userData: any) => {
};

/**
* **Work:** verifys the user based on the userId and secret sent to the user's email
* @description verifys the user based on the userId and secret sent to the user's email
* @param {String} userId
* @param {String} secret
* @returns {Object} response status
Expand Down Expand Up @@ -91,7 +91,7 @@ const verifyUser = async (userId: string, secret: string) => {
};

/**
* **Work:** log in the user based on emailId and password
* @description log in the user based on emailId and password
* @param {Object} userData
* @returns {Object} response
*/
Expand All @@ -117,6 +117,10 @@ const loginUser = async (userData: any) => {
}
};

/**
* @description returns the state of current user
* @returns {Object} Session
*/
const getCurrentUser = async () => {
try {
return account.get();
Expand All @@ -127,12 +131,16 @@ const getCurrentUser = async () => {
return null;
};

/**
* @description logs out the user by clearing current session
* @returns {Object} returns session
*/
const logoutUser = async () => {
return await account.deleteSession("current");
};

/**
* **Work:** Save Data into Appwrite Database
* @description Save Data into Appwrite Database
* @param {Object} session
* @returns {Object} dbResponse
*/
Expand All @@ -145,7 +153,7 @@ const saveDataToDatabase = async (session: any) => {
fullName: session.name,
createdAt: session.$createdAt,
isVerified: session.emailVerification,
userId: session.$id,
accountId: session.$id,
username: username,
});

Expand Down Expand Up @@ -178,4 +186,20 @@ const isLoggedIn = async (): Promise<any> => {
return false;
};

export { registerUser, verifyUser, loginUser, logoutUser, isLoggedIn };
/**
* @description get single user data based on account id
* @param id
* @returns
*/
const getSingleUser = async (id: string) => {
try {
const tweets = await db.getDocument(palettegramDB, usersCollection, id);
if (tweets) {
return tweets;
}
} catch (error: any) {
console.log(error);
}
};

export { registerUser, verifyUser, loginUser, logoutUser, isLoggedIn, getSingleUser };
109 changes: 109 additions & 0 deletions src/backend/bookmarks.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"use client";

import { account, db, ID, Query, palettegramDB, bookmarksCollection } from "./appwrite.config";

/**
* @abstract filtering bookmarks
* @param {string[]} bookmarks
* @param {string} postId
* @returns {string[]}
*/
const removePostIdFromBookmarks = function (bookmarks: string[], postId: string): string[] {
let idx = bookmarks.indexOf(postId);

let beforeIdx = bookmarks.slice(0, idx);

let afterIdx = bookmarks.slice(idx + 1, bookmarks.length);

return [...beforeIdx, ...afterIdx];
};

const getBookmarks = async (accountId: string) => {
try {
const getSavedBookmarkData = await db.listDocuments(palettegramDB, bookmarksCollection, [
Query.equal("accountId", accountId),
]);

return getSavedBookmarkData;
} catch (error) {
console.log(error);
}
};

const saveBookmark = async (accountId: string, postId: string) => {
try {
console.log(accountId, postId);
const getSavedBookmarkData = await getBookmarks(accountId);

if (!getSavedBookmarkData) {
throw new Error("Account does not exist");
}

const documentId = getSavedBookmarkData.documents[0].$id;
let oldBookmarkArray = getSavedBookmarkData.documents[0].bookmark;

oldBookmarkArray.push(postId);

const updatedData = await db.updateDocument(palettegramDB, bookmarksCollection, documentId, {
bookmark: oldBookmarkArray,
});

if (!updatedData) {
throw new Error();
}

return updatedData;
} catch (error) {
throw new Error();
}
};

const removeBookmark = async (accountId: string, postId: string) => {
try {
console.log(accountId, postId);

const getSavedBookmarkData = await getBookmarks(accountId);

if (!getSavedBookmarkData) {
throw new Error("Account does not exist");
}

const documentId = getSavedBookmarkData.documents[0].$id;
let oldBookmarkArray = getSavedBookmarkData.documents[0].bookmark;

let newBookmarkArray: string[] = removePostIdFromBookmarks(oldBookmarkArray, postId);

const updatedData = await db.updateDocument(palettegramDB, bookmarksCollection, documentId, {
bookmark: newBookmarkArray,
});

if (!updatedData) {
throw new Error();
}

return updatedData;
} catch (error) {
throw new Error();
}
};

const createBookmarkEntry = async (accountId: string, postId: string) => {
try {
console.log(accountId, postId);

const bookmarkDocs = await db.createDocument(palettegramDB, bookmarksCollection, ID.unique(), {
accountId: accountId,
bookmark: [postId],
});

if (!bookmarkDocs) {
throw new Error("Account does not exist");
}

return bookmarkDocs;
} catch (error) {
throw new Error();
}
};

export { saveBookmark, removeBookmark, createBookmarkEntry, getBookmarks };
51 changes: 39 additions & 12 deletions src/backend/posts.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import {
bucketStorage,
} from "./appwrite.config";

/**
* @description Save a single post to database
* @param data
* @returns
*/
const savePostToDb = async (data: any) => {
try {
const post = await db.createDocument(palettegramDB, postsCollection, ID.unique(), data);
Expand All @@ -22,6 +27,10 @@ const savePostToDb = async (data: any) => {
}
};

/**
* @description get all posts present in the database
* @returns {Object} posts db
*/
const getAllPosts = async () => {
try {
const tweets = await db.listDocuments(palettegramDB, postsCollection);
Expand All @@ -35,6 +44,11 @@ const getAllPosts = async () => {
}
};

/**
* @description gets single document based on the id
* @param id
* @returns
*/
const getSinglePost = async (id: string) => {
try {
const tweets = await db.getDocument(palettegramDB, postsCollection, id);
Expand All @@ -46,17 +60,11 @@ const getSinglePost = async (id: string) => {
}
};

const getSingleUser = async (id: string) => {
try {
const tweets = await db.getDocument(palettegramDB, usersCollection, id);
if (tweets) {
return tweets;
}
} catch (error: any) {
console.log(error);
}
};

/**
* @description get user post based on account id
* @param userId
* @returns
*/
const getAllUserPosts = async (userId: string) => {
try {
const tweets = await db.listDocuments(palettegramDB, postsCollection, [
Expand All @@ -71,6 +79,11 @@ const getAllUserPosts = async (userId: string) => {
}
};

/**
* @description like tweet api
* @param tweet
* @returns
*/
const likeTweet = async (tweet: any) => {
try {
const tweets = await db.updateDocument(palettegramDB, postsCollection, tweet.$id, {
Expand All @@ -84,6 +97,11 @@ const likeTweet = async (tweet: any) => {
}
};

/**
* @description image adding api. Save image into bucket
* @param image
* @returns
*/
const addNewImage = async (image: any) => {
try {
const resImage = await storage.createFile(bucketStorage, ID.unique(), image);
Expand All @@ -96,6 +114,11 @@ const addNewImage = async (image: any) => {
}
};

/**
* @description get image url from bucket
* @param imageId
* @returns
*/
const getImageUrl = (imageId: string) => {
try {
if (!imageId) {
Expand All @@ -110,6 +133,11 @@ const getImageUrl = (imageId: string) => {
}
};

/**
* @description delete image from bucket
* @param id
* @returns
*/
const deleteImage = async (id: string) => {
try {
const resImage = await storage.deleteFile(bucketStorage, id);
Expand All @@ -123,7 +151,6 @@ const deleteImage = async (id: string) => {

export {
savePostToDb,
getSingleUser,
getAllPosts,
getAllUserPosts,
getSinglePost,
Expand Down
2 changes: 1 addition & 1 deletion src/components/core/createPost/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const CreatePost = () => {
const imageArray = [imageURL];

const finalDataToUpload: PostInstanceType = {
userId: userIdFromCookies,
accountId: userIdFromCookies,
postTitle: postTitle,
postImage: imageArray.length > 0 ? imageArray : [],
colors: [],
Expand Down
2 changes: 1 addition & 1 deletion src/components/core/footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from "react";
export default function Footer() {
return (
<section className="mt-12 text-center">
<p className="py-4 text-secondary-light dark:text-primary-light">
<p className="py-4 text-base text-secondary-light dark:text-primary-light">
Copyright &copy; {new Date().getFullYear()} Palettegram | All Rights Reserved.
</p>
</section>
Expand Down
Loading

1 comment on commit 9d6ba92

@vercel
Copy link

@vercel vercel bot commented on 9d6ba92 Dec 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.