Skip to content

developer-mustafa/zoom-1.0

Repository files navigation


Project Banner
typescript nextdotjs tailwindcss

A Zoom Clone Mustafa Rahman

Build this project step by step with our detailed tutorial on Learn with Mustafa YouTube.
## 📋 Table of Contents 1. 🤖 [Introduction](#introduction) 2. ⚙️ [Tech Stack](#tech-stack) 3. 🔋 [Features](#features) 4. 🤸 [Quick Start](#quick-start) 5. 🕸️ [Assets & Code](#snippets) 6. 🚀 [More](#more) ## 🤖 Introduction Built with the latest Next.js and TypeScript, this project replicates Zoom, a widely used video conferencing tool. It enables users to securely log in, create meetings and access various meeting functionalities such as recording, screen sharing, and managing participants. ## ⚙️ Tech Stack - Next.js - TypeScript - Clerk - getstream - shadcn - Tailwind CSS ## 🔋 Features 👉 **Authentication**: Implements authentication and authorization features using Clerk, allowing users to securely log in via social sign-on or traditional email and password methods, while ensuring appropriate access levels and permissions within the platform. 👉 **New Meeting**: Quickly start a new meeting, configuring camera and microphone settings before joining. 👉 **Meeting Controls**: Participants have full control over meeting aspects, including recording, emoji reactions, screen sharing, muting/unmuting, sound adjustments, grid layout, participant list view, and individual participant management (pinning, muting, unmuting, blocking, allowing video share). 👉 **Exit Meeting**: Participants can leave a meeting, or creators can end it for all attendees. 👉 **Schedule Future Meetings**: Input meeting details (date, time) to schedule future meetings, accessible on the 'Upcoming Meetings' page for sharing the link or immediate start. 👉 **Past Meetings List**: Access a list of previously held meetings, including details and metadata. 👉 **View Recorded Meetings**: Access recordings of past meetings for review or reference. 👉 **Personal Room**: Users have a personal room with a unique meeting link for instant meetings, shareable with others. 👉 **Join Meetings via Link**: Easily join meetings created by others by providing a link. 👉 **Secure Real-time Functionality**: All interactions within the platform are secure and occur in real-time, maintaining user privacy and data integrity. 👉 **Responsive Design**: Follows responsive design principles to ensure optimal user experience across devices, adapting seamlessly to different screen sizes and resolutions. and many more, including code architecture and reusability. ## 🤸 Quick Start Follow these steps to set up the project locally on your machine. **Prerequisites** Make sure you have the following installed on your machine: - [Git](https://git-scm.com/) - [Node.js](https://nodejs.org/en) - [npm](https://www.npmjs.com/) (Node Package Manager) **Cloning the Repository** **Installation** Install the project dependencies using npm: ```bash npm install ``` **Set Up Environment Variables** Create a new file named `.env` in the root of your project and add the following content: ```env NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY= CLERK_SECRET_KEY= NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up NEXT_PUBLIC_STREAM_API_KEY= STREAM_SECRET_KEY= ``` Replace the placeholder values with your actual Clerk & getstream credentials. You can obtain these credentials by signing up on the [Clerk website](https://clerk.com/) and [getstream website](https://getstream.io/) **Running the Project** ```bash npm run dev ``` Open [http://localhost:3000](http://localhost:3000) in your browser to view the project. ## 🕸️ Snippets
app/globals.css ```css @tailwind base; @tailwind components; @tailwind utilities; * { margin: 0; padding: 0; box-sizing: border-box; } /* ======== stream css overrides ======== */ .str-video__call-stats { max-width: 500px; position: relative; } .str-video__speaker-layout__wrapper { max-height: 700px; } .str-video__participant-details { color: white; } .str-video__menu-container { color: white; } .str-video__notification { color: white; } .str-video__participant-list { background-color: #1c1f2e; padding: 10px; border-radius: 10px; color: white; height: 100%; } .str-video__call-controls__button { height: 40px; } .glassmorphism { background: rgba(255, 255, 255, 0.25); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } .glassmorphism2 { background: rgba(18, 17, 17, 0.25); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); } /* ==== clerk class override ===== */ .cl-userButtonPopoverActionButtonIcon { color: white; } .cl-logoBox { height: 40px; } .cl-dividerLine { background: #252a41; height: 2px; } .cl-socialButtonsIconButton { border: 3px solid #565761; } .cl-internal-wkkub3 { color: white; } .cl-userButtonPopoverActionButton { color: white; } /* =============================== */ @layer utilities { .flex-center { @apply flex justify-center items-center; } .flex-between { @apply flex justify-between items-center; } } /* animation */ .show-block { width: 100%; max-width: 350px; display: block; animation: show 0.7s forwards linear; } @keyframes show { 0% { animation-timing-function: ease-in; width: 0%; } 100% { animation-timing-function: ease-in; width: 100%; } } ```
tailwind.config.ts ```typescript import type { Config } from 'tailwindcss'; const config = { darkMode: ['class'], content: [ './pages/**/*.{ts,tsx}', './components/**/*.{ts,tsx}', './app/**/*.{ts,tsx}', './src/**/*.{ts,tsx}', ], prefix: '', theme: { container: { center: true, padding: '2rem', screens: { '2xl': '1400px', }, }, extend: { colors: { dark: { 1: '#1C1F2E', 2: '#161925', 3: '#252A41', 4: '#1E2757', }, blue: { 1: '#0E78F9', }, sky: { 1: '#C9DDFF', 2: '#ECF0FF', 3: '#F5FCFF', }, orange: { 1: '#FF742E', }, purple: { 1: '#830EF9', }, yellow: { 1: '#F9A90E', }, }, keyframes: { 'accordion-down': { from: { height: '0' }, to: { height: 'var(--radix-accordion-content-height)' }, }, 'accordion-up': { from: { height: 'var(--radix-accordion-content-height)' }, to: { height: '0' }, }, }, animation: { 'accordion-down': 'accordion-down 0.2s ease-out', 'accordion-up': 'accordion-up 0.2s ease-out', }, backgroundImage: { hero: "url('/images/hero-background.png')", }, }, }, plugins: [require('tailwindcss-animate')], } satisfies Config; export default config; ```
components/MeetingCard.tsx ```typescript "use client"; import Image from "next/image"; import { cn } from "@/lib/utils"; import { Button } from "./ui/button"; import { avatarImages } from "@/constants"; import { useToast } from "./ui/use-toast"; interface MeetingCardProps { title: string; date: string; icon: string; isPreviousMeeting?: boolean; buttonIcon1?: string; buttonText?: string; handleClick: () => void; link: string; } const MeetingCard = ({ icon, title, date, isPreviousMeeting, buttonIcon1, handleClick, link, buttonText, }: MeetingCardProps) => { const { toast } = useToast(); return (
upcoming

{title}

{date}

{avatarImages.map((img, index) => ( attendees 0 })} style={{ top: 0, left: index * 28 }} /> ))}
+5
{!isPreviousMeeting && (
{buttonIcon1 && ( feature )}   {buttonText} { navigator.clipboard.writeText(link); toast({ title: "Link Copied", }); }} className="bg-dark-4 px-6" > feature   Copy Link
)}
); }; export default MeetingCard; ```
# zoom-1.0 # zoom-1.0