stage1:
we are going to set up backend and moving forward for frontend
s1: create frontend and backend folders s2: in frontend folder---npm create vite @latest .-------. helps to create vite in frontend folder s3: in backend npm init -y and laster install required dependencies s4: dependencies --npm install express bcrypt jsonwebtoken cookie-parser cors dotenv mongoose stream-chat
s5: set up express and signup, login, logout routes in server.js NOTE: we create server.js inside src folder R: similar to frontend src--good practice
s6: set up .env for accessing enviromental variables s7: here we are using routes folder and accomidating auth.route.js and we are exporting routes and in server.js we are using this middelware ---app.use('/api/auth', authRoutes); s8: lly creating controllers folder and accomidating auth.controller.js and actual code is written here
//--------------------------------------------------------------------------------------------------------- CONNECTING DB --MONGODB
s1: in mongo atlas create a new project and grab URL s2: in src create a folder lib---and db.js ---create connenctDBfunction and export the same s3: in server.js import the same and in app.listen---USING F(X) connectDB()----connect to db
Note: in mongo-atlas --- in network access---ip access list---tick access from anywhere 0.0.0.0/0
//--------------------------------------------------------------------------------------------------------- setting up video calling platform using stream ---link--- https://dub.sh/getstream.io
stream is a video calling platform---helps in chating, video calling and can be scalled to millions of users
s1: login to streamify---and create org with your name---teje999 s2: create app---streamify999---and we get app access key and secret s3: in .env access STREM_API_KEY and STREAM_API_SECRET
//--------------------------------------------------------------------------------------------------------- SIGNUP ENDPOINT
FLOW--for new user--we will redirect to signup page---upon signup---we will be re-directed onboarding page where all details are collected
refer diagram
s1: in src create a folder models s2: in create create User.js file with-----userSchema and userModel and export the same s3: after creating schema and before creating model we use a pre hook to hash the password and save the same to DB
FLOW CHECK: REF diagram user clicks a buttton---signup/login-- when signup is clicked we get credintials and saved to DB
redirected to login page check user credintials validate credintials use JWT services and generate JWT token send JWT (TOKEN) in cookies display chat page
code sign up in controller---auth.controller.js check newUser credentials-----all good----create token and pass token in res
to generate random key using bash/zsh ----used for JWT_SECRET in .env open zsh/bash openssl rand -base64 32
//----------------------------------------------------------------------------------------------------------- LOGIN ENDPOINT
s1: check input user creditials s2: all good , create JWT and pass in response
//------------------------------------------------------------------------------------------------------------ LOGOUT ENDPOINT
s1: in res clear cookie res.clearCookie("jwt") pass name of the cookie--jwt s2: send status and json() messsage for logout
//--------------------------------------------------------------------------------------------------------------- adddng user to stream-chat
s1: in lib create a folder stream.js---create a function with
1. Creates a StreamChat client instance using API key + secret.
This object allows you to:
Create/update users
Generate user tokens
Manage channels
Send messages
2. Upsert (create/update) Stream User
s2: in auth.controller.js in signup---using this f(x) create stream user
//------------------------------------------------------------------------------------------ ONBOARDING ENDPOINT
steps this onboarding step is next to signup---so in req we have cookie we make sure onboarding route is protected by pass a middelware---protectRoute
in middelware folder create a file auth.middelware.js
- export a function protectRoute---- first we verity the jwt cookie
- if valid---in jwt---we passed user id as payload
- using user_id we extract user info and send it through request as req.user----to onboarding
//-------------------------------------------------------------------------------------------- Creating model for FriendRequest in models
once onboarding is done---user is now landed to home page where, he can see recommanded users, friends--- all these user activities are handled using user.route.js and user.controller.js---where the user.route.js is imported in server.js as usual
USER ACTIVITIES
Get Recommended Users & Friends Endpoint
Send Friend Request Endpoint
Accept Friend Request Endpoint
Completing Our User Routes acceptFriendRequest, getFriendRequests, getMyFriends, getOutgoingFriendReqs, getRecommendedUsers, sendFriendRequest,
//--------------------------------------------------------------------------------------------------------- CHAT ROUTES in order to chat we need to have stream token so we create stream token for the same chat controller chat route
note: we are creating streamToken in steam.js @lib and importing the same http://localhost:5001/api/chat/token----GET Request---check if token is generated Note: as the route is protected---we need to provide jwt in auth bearer
//----------------------------------------------------------------------------------------------------------
FRONTEND-- keep the terminal for backend and open new terminal ---for frontend and npm run dev SETUP TAILWIND CSS AND DAISY UI s1: set up tailwind css---latest is v4 but we go with version 3 1.http://v3.tailwindcss.com/docs/installation 2.follow process
Note--install tailwind IntelliSense---extension---for better tailwind highlighting
s2: install daisy ui--for easy usage of tailwind and later we will be using thermes Note: latest version is v5 and we go with v4 https://v4.daisyui.com/docs/install/
- npm i -D daisyui@v4
- in tailwind.config.js add---require('daisyui'), in plugin
- check button component
- check theme using daisy UI----in tailwind config---add themes to access daisyUI themes---as shown in doc
- in App.jsx add className--"data-theme=forest" and check
//--------------------------------------------------------------------------------------------------------- SETUP PAGES USING REACT-ROUTER-DOM s1: install react-router-dom---for this we are going wiht latest one v7----install react-router--follow official documentation--www.react router----get started npm i react-router
s2: in main.jsx---import {BrowserRouter} from react-router and wrap App with the same As we wrapped our application with , we can use any component comming from router in our Application
s3: in src create an folder pages and create different pages in it s4: in App.jsx ---using and access each page
React-hot-toast React Hot Toast is a lightweight, accessible, and highly customizable library for adding "smoking hot" toast notifications to React and Next.js applications
follow offical doc--https://react-hot-toast.com/ 1: in simple install react-hot-toast 2: add Toast component at bottom 3: using toast method create toast---toast("Hello World")
//------------------------------------------------------------------------------------------------- set up AXIOS and TANSTACK query
WITHOUT USING TANSTACK ----- a simple data fetch taked these lines of code //creating data,isLoading and error variables-----using useState // const [data, setData] = useState([]); // const [isLoading, setIsLoading ] = useState(false); // const [error, setError ] = useState(null);
//using-----useEffect() and fetching simple data-----adjusting variables according to the same // useEffect(() => { // const getData = async () => { // setIsLoading(true);
// try { // const data = await fetch("https://jsonplaceholder.typicode.com/todos"); //fetching fake data // const json = await data.json(); // setData(json); // } catch (error) { // setError(error); // } finally { // setIsLoading(false); // } // }; // getData(); // }, []);
// console.log(data);
USING TANSTACK------------------- S1: TANSTACK setup----tanstack.com/query/latest/doc---installation----npm i @tanstack/react-query s2: in main.jsx----import---and create queryClient-----and wrap the App with QueryClientProvider import { useQuery, useMutation, useQueryClient, QueryClient, QueryClientProvider, } from '@tanstack/react-query'
//create queryClient const queryClient = new QueryClient();
//wrapping App with QueryClientProvider
NOW we can use tanstack anywhere in our application
we have queries and mutation----- queries for fetching data---GET mutation for PUT,POST,DELETE operations
in App.jsx-----no need to create useState variables and useEffect-----just by using query----we can fetch data //Axios //react query---tanstack query const {data,isLoading,error} = useQuery({queryKey:['todos'], queryFn: async()=>{ const res = await fetch("https://jsonplaceholder.typicode.com/todos"); const data = res.json(); return data; }, });
console.log(data);
//-------------------------------------------------------------------------------------- SIGNUP page
pic---storyset.com color---1FB854
s1: in App.jsx---using useQuery(tanStack query)---we are geting authData---- s2: in Routes---using this authData----check if the user is authorized or not if not ----- s3: in SignUpPage.jsx---code for img and from---Note: here we are using----MUTATATION of tanstack query---and updating signup data
Note: after logging in from frontend, we can accesss token from dev tools----(inspect)----Applications----cookies and DELETE the same
//--------------------------------------------------------------------------------------
//once after signing up----we move to onboarding------in between we handle LOADING----using component and make use of the same in App.jsx and where ever needed
//as we will be usisng tanstack query multiple times----it better to creat a custom hook for the same //tanstack query const { data: authData, isLoading, error, } = useQuery({ queryKey: ["authUser"], queryFn: async () => { const res = await axiosInstance.get("/auth/me"); //CORS error----=>in backend server import "cors" ----and app.use(cors()); return res.data; }, retry: false, //tan stack will retry only once----generally +3 times });
const authUser = authData?.user;
CUSTOM HOOK: useAuthUser------Note: it is mandatory to start custome hook with use----hooks---useAuthUser.js
//-------------------------------------------------------------------------------------------- Onboarding page
Mutation is the Heart
//login page---------------------------------------------------------------------------------- same //-------------------------------------------------------------------------------------------- // Layout Component and logout-----SIDEBAR AND NAVBAR layouts are re-usable components---used in various pages --- homePage ----sideBar and NavBar chatPage-----NavBar
s1: we wrap the home page and other pages with component s2: in Layouts component---in Layouts.jsx----include SideBar.jsx and NavBar.jsx s3: code SideBar and NavBar s4: in Navbar---- component should be addressed
//--------------------------------------------------------------------------------------------
Themes---we are proving a dropdown with various themes------and setting up data-theme in App.jsx to selected theme
the theme applied ---should be global we can use various methods ----------like reactContext,rexu ----but we go with zustand(easy and effiecient)
s1: npm i zustand s2: create an folder store and create a custom hook useThemeStore.jsx
code---eg import {create } from "zustand";
export const useThemeStore = create((set)=>({ //create an object with theme and setTheme theme:"coffee", setTheme: (theme)=>set({theme}), }))
Now we can use this theme as global object in App.jsx
s3: in App.jsx
import useThemeStore;
use useThemeStore(); custom hook and destructure to {theme} now pass this value to data-theme in Route
Note: we are passing this value in data-theme of home.jsx route--------and signup n login page are set to default theme forest
//------------------------------------------------------------------------------------------------------
Note: update data-theme of component ----so that same theme applies even in page Loader //-------------------------------------------------------------------------------------------------------------- //Home Page---Refer diagram
//Notifications Page---Refer diagram //------------------------------------------------------------------------------------------------ //Chat Page
install stream-chat and stream-chat-react documentation ----getStream.io----chatMessaging documentation
here we are setting up steram Channel and rest is handled by STREAM
note: steam css file is to incorporated in index.css
and in main.jsx before importing----index.css---we need tp import import "stream-chat-react/dist/css/v2/index.css";----------------as part of stream-css
//--------------------------------------------------------------------------------------------------
Deployment s1: create a package.json----npm init---- in root ie., outside frontend and backend s2: in backend package.json ------in scripts "dev": "nodemon src/server.js" "start": "node src/server.js" s3: push code to Github repo----before that s4: we dont push nodemodules into git---so delete nodemodules in frontend and backend---and upon deployment this need to be addressed s5: in package.json in root ----in scripts--- "build": "npm install --prefix backend && npm install --prefix frontend && npm run build --prefix frontend"
npm install---helps in installing node modules
npm run build-- helps in creating a dist folder in frontend---for the sake of optimisation
s6: in root package.json----inside scripts---add "start" : "npm run start --prefix backend"-----helps to start backend with node and not nodmon
s7:in backend server.js----10 lines of code for deployment
import path from "path"-----comes from node.js and no need to install
const __dirname = path.resolve();
after routes
if(process.env.NODE_ENV == "production"){
app.use(express.static(path.join(__dirname, "../frontend/dist")));
}
//what this does----after all routes in backend addressed ---- we take dist from frontend and make it static
app.get("*", (req,res)=>{
res.sendFile(path.join(__dirname, "../frontend", "dist", "index.html"));
})
//what it does----any other requset---other than backend should address react----throught index.html
s8: in .env file----NODE_ENV=production s9: in axios---we are addressing -----baseURL = to localhost/5001/api----but in production after deployment---new address is provided---NEED TO be addressed
const BASE_URL = import.meta.env.MODE == "development"? "http://localhost:5001/api" : "/api" baseURL =BASE_URL;
S10: now we should be able to run the app as earlier---check for the same from root npm run build---//installs required npm packages npm start ---//starts the app in backend----inside backend frontend is handled
s11: crate a new git hub repo---in github and push code to repo-----BEFORE THAT PUSH .gitignore to root Note: move .gitignore from frontend to root and add .env into .gitignore
git init
git add .
git commit -m "Initial Commit"
git branch -M master
git remote add origin "GIT_REPO"
git push -u origin master
s12: login render with Github NEW button---web service select GIT REPO give BUILT and START commands------npm run built-----npm run start add enviromental variables of rontend and backend----note: no need to NODE_ENV=production-----Reason: render knows it is production