{"id":13901292,"url":"https://github.com/adrianhajdin/zoom-clone","last_synced_at":"2025-05-14T19:07:12.772Z","repository":{"id":230357330,"uuid":"778979697","full_name":"adrianhajdin/zoom-clone","owner":"adrianhajdin","description":"Learn to develop a professional enterprise-ready video conferencing app in hours using Next.js 14, Stream, and Tailwind CSS.","archived":false,"fork":false,"pushed_at":"2024-10-29T09:23:51.000Z","size":705,"stargazers_count":1100,"open_issues_count":18,"forks_count":399,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-13T15:06:56.054Z","etag":null,"topics":["clerk","getstream-io","nextjs","reactjs"],"latest_commit_sha":null,"homepage":"https://jsmastery.pro","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adrianhajdin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-28T19:45:04.000Z","updated_at":"2025-04-13T13:32:41.000Z","dependencies_parsed_at":"2024-10-29T10:47:58.761Z","dependency_job_id":null,"html_url":"https://github.com/adrianhajdin/zoom-clone","commit_stats":null,"previous_names":["adrianhajdin/zoom-clone"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrianhajdin%2Fzoom-clone","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrianhajdin%2Fzoom-clone/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrianhajdin%2Fzoom-clone/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrianhajdin%2Fzoom-clone/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adrianhajdin","download_url":"https://codeload.github.com/adrianhajdin/zoom-clone/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254209859,"owners_count":22032897,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clerk","getstream-io","nextjs","reactjs"],"created_at":"2024-08-06T21:01:08.889Z","updated_at":"2025-05-14T19:07:10.644Z","avatar_url":"https://github.com/adrianhajdin.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","App"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cbr /\u003e\n    \u003ca href=\"https://youtu.be/R8CIO1DZ2b8\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://github.com/adrianhajdin/zoom-clone/assets/67959015/f09a8421-67d3-45ce-b9bc-a791cdc2774b\" alt=\"Project Banner\"\u003e\n    \u003c/a\u003e\n  \n  \u003cbr /\u003e\n\n  \u003cdiv\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-TypeScript-black?style=for-the-badge\u0026logoColor=white\u0026logo=typescript\u0026color=3178C6\" alt=\"typescript\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-Next_JS-black?style=for-the-badge\u0026logoColor=white\u0026logo=nextdotjs\u0026color=000000\" alt=\"nextdotjs\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-Tailwind_CSS-black?style=for-the-badge\u0026logoColor=white\u0026logo=tailwindcss\u0026color=06B6D4\" alt=\"tailwindcss\" /\u003e\n  \u003c/div\u003e\n\n  \u003ch3 align=\"center\"\u003eA Zoom Clone\u003c/h3\u003e\n\n   \u003cdiv align=\"center\"\u003e\n     Build this project step by step with our detailed tutorial on \u003ca href=\"https://www.youtube.com/@javascriptmastery/videos\" target=\"_blank\"\u003e\u003cb\u003eJavaScript Mastery\u003c/b\u003e\u003c/a\u003e YouTube. Join the JSM family!\n    \u003c/div\u003e\n\u003c/div\u003e\n\n## 📋 \u003ca name=\"table\"\u003eTable of Contents\u003c/a\u003e\n\n1. 🤖 [Introduction](#introduction)\n2. ⚙️ [Tech Stack](#tech-stack)\n3. 🔋 [Features](#features)\n4. 🤸 [Quick Start](#quick-start)\n5. 🕸️ [Assets \u0026 Code](#snippets)\n6. 🚀 [More](#more)\n\n## 🚨 Tutorial\n\nThis repository contains the code corresponding to an in-depth tutorial available on our YouTube channel, \u003ca href=\"https://www.youtube.com/@javascriptmastery/videos\" target=\"_blank\"\u003e\u003cb\u003eJavaScript Mastery\u003c/b\u003e\u003c/a\u003e. \n\nIf you prefer visual learning, this is the perfect resource for you. Follow our tutorial to learn how to build projects like these step-by-step in a beginner-friendly manner!\n\n\u003ca href=\"https://youtu.be/R8CIO1DZ2b8\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/sujatagunale/EasyRead/assets/151519281/1736fca5-a031-4854-8c09-bc110e3bc16d\" /\u003e\u003c/a\u003e\n\n## \u003ca name=\"introduction\"\u003e🤖 Introduction\u003c/a\u003e\n\nBuilt 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.\n\nIf you're getting started and need assistance or face any bugs, join our active Discord community with over 30 thousand members. It's a place where people help each other out.\n\n\u003ca href=\"https://discord.com/invite/n6EdbFJ\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/sujatagunale/EasyRead/assets/151519281/618f4872-1e10-42da-8213-1d69e486d02e\" /\u003e\u003c/a\u003e\n\n## \u003ca name=\"tech-stack\"\u003e⚙️ Tech Stack\u003c/a\u003e\n\n- Next.js\n- TypeScript\n- Clerk\n- getstream\n- shadcn\n- Tailwind CSS\n\n## \u003ca name=\"features\"\u003e🔋 Features\u003c/a\u003e\n\n\n👉 **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.\n\n👉 **New Meeting**: Quickly start a new meeting, configuring camera and microphone settings before joining.\n\n👉 **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).\n\n👉 **Exit Meeting**: Participants can leave a meeting, or creators can end it for all attendees.\n\n👉 **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.\n\n👉 **Past Meetings List**: Access a list of previously held meetings, including details and metadata.\n\n👉 **View Recorded Meetings**: Access recordings of past meetings for review or reference.\n\n👉 **Personal Room**: Users have a personal room with a unique meeting link for instant meetings, shareable with others.\n\n👉 **Join Meetings via Link**: Easily join meetings created by others by providing a link.\n\n👉 **Secure Real-time Functionality**: All interactions within the platform are secure and occur in real-time, maintaining user privacy and data integrity.\n\n👉 **Responsive Design**: Follows responsive design principles to ensure optimal user experience across devices, adapting seamlessly to different screen sizes and resolutions.\n\nand many more, including code architecture and reusability. \n\n## \u003ca name=\"quick-start\"\u003e🤸 Quick Start\u003c/a\u003e\n\nFollow these steps to set up the project locally on your machine.\n\n**Prerequisites**\n\nMake sure you have the following installed on your machine:\n\n- [Git](https://git-scm.com/)\n- [Node.js](https://nodejs.org/en)\n- [npm](https://www.npmjs.com/) (Node Package Manager)\n\n**Cloning the Repository**\n\n```bash\ngit clone https://github.com/adrianhajdin/zoom-clone.git\ncd zoom-clone\n```\n\n**Installation**\n\nInstall the project dependencies using npm:\n\n```bash\nnpm install\n```\n\n**Set Up Environment Variables**\n\nCreate a new file named `.env` in the root of your project and add the following content:\n\n```env\nNEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=\nCLERK_SECRET_KEY=\n\nNEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in\nNEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up\n\nNEXT_PUBLIC_STREAM_API_KEY=\nSTREAM_SECRET_KEY=\n```\n\nReplace the placeholder values with your actual Clerk \u0026 getstream credentials. You can obtain these credentials by signing up on the [Clerk website](https://clerk.com/) and [getstream website](https://getstream.io/)\n\n**Running the Project**\n\n```bash\nnpm run dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000) in your browser to view the project.\n\n## \u003ca name=\"snippets\"\u003e🕸️ Snippets\u003c/a\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003eapp/globals.css\u003c/code\u003e\u003c/summary\u003e\n\n```css\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n* {\n  margin: 0;\n  padding: 0;\n  box-sizing: border-box;\n}\n\n/* ======== stream css overrides ======== */\n.str-video__call-stats {\n  max-width: 500px;\n  position: relative;\n}\n\n.str-video__speaker-layout__wrapper {\n  max-height: 700px;\n}\n\n.str-video__participant-details {\n  color: white;\n}\n\n.str-video__menu-container {\n  color: white;\n}\n\n.str-video__notification {\n  color: white;\n}\n\n.str-video__participant-list {\n  background-color: #1c1f2e;\n  padding: 10px;\n  border-radius: 10px;\n  color: white;\n  height: 100%;\n}\n\n.str-video__call-controls__button {\n  height: 40px;\n}\n\n.glassmorphism {\n  background: rgba(255, 255, 255, 0.25);\n  backdrop-filter: blur(4px);\n  -webkit-backdrop-filter: blur(4px);\n}\n.glassmorphism2 {\n  background: rgba(18, 17, 17, 0.25);\n  backdrop-filter: blur(8px);\n  -webkit-backdrop-filter: blur(8px);\n}\n\n/* ==== clerk class override ===== */\n\n.cl-userButtonPopoverActionButtonIcon {\n  color: white;\n}\n\n.cl-logoBox {\n  height: 40px;\n}\n.cl-dividerLine {\n  background: #252a41;\n  height: 2px;\n}\n\n.cl-socialButtonsIconButton {\n  border: 3px solid #565761;\n}\n\n.cl-internal-wkkub3 {\n  color: white;\n}\n.cl-userButtonPopoverActionButton {\n  color: white;\n}\n\n/* =============================== */\n\n@layer utilities {\n  .flex-center {\n    @apply flex justify-center items-center;\n  }\n\n  .flex-between {\n    @apply flex justify-between items-center;\n  }\n}\n\n/* animation */\n\n.show-block {\n  width: 100%;\n  max-width: 350px;\n  display: block;\n  animation: show 0.7s forwards linear;\n}\n\n@keyframes show {\n  0% {\n    animation-timing-function: ease-in;\n    width: 0%;\n  }\n\n  100% {\n    animation-timing-function: ease-in;\n    width: 100%;\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003etailwind.config.ts\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nimport type { Config } from 'tailwindcss';\n\nconst config = {\n  darkMode: ['class'],\n  content: [\n    './pages/**/*.{ts,tsx}',\n    './components/**/*.{ts,tsx}',\n    './app/**/*.{ts,tsx}',\n    './src/**/*.{ts,tsx}',\n  ],\n  prefix: '',\n  theme: {\n    container: {\n      center: true,\n      padding: '2rem',\n      screens: {\n        '2xl': '1400px',\n      },\n    },\n    extend: {\n      colors: {\n        dark: {\n          1: '#1C1F2E',\n          2: '#161925',\n          3: '#252A41',\n          4: '#1E2757',\n        },\n        blue: {\n          1: '#0E78F9',\n        },\n        sky: {\n          1: '#C9DDFF',\n          2: '#ECF0FF',\n          3: '#F5FCFF',\n        },\n        orange: {\n          1: '#FF742E',\n        },\n        purple: {\n          1: '#830EF9',\n        },\n        yellow: {\n          1: '#F9A90E',\n        },\n      },\n      keyframes: {\n        'accordion-down': {\n          from: { height: '0' },\n          to: { height: 'var(--radix-accordion-content-height)' },\n        },\n        'accordion-up': {\n          from: { height: 'var(--radix-accordion-content-height)' },\n          to: { height: '0' },\n        },\n      },\n      animation: {\n        'accordion-down': 'accordion-down 0.2s ease-out',\n        'accordion-up': 'accordion-up 0.2s ease-out',\n      },\n      backgroundImage: {\n        hero: \"url('/images/hero-background.png')\",\n      },\n    },\n  },\n  plugins: [require('tailwindcss-animate')],\n} satisfies Config;\n\nexport default config;\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003ecomponents/MeetingCard.tsx\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\n\"use client\";\n\nimport Image from \"next/image\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"./ui/button\";\nimport { avatarImages } from \"@/constants\";\nimport { useToast } from \"./ui/use-toast\";\n\ninterface MeetingCardProps {\n  title: string;\n  date: string;\n  icon: string;\n  isPreviousMeeting?: boolean;\n  buttonIcon1?: string;\n  buttonText?: string;\n  handleClick: () =\u003e void;\n  link: string;\n}\n\nconst MeetingCard = ({\n  icon,\n  title,\n  date,\n  isPreviousMeeting,\n  buttonIcon1,\n  handleClick,\n  link,\n  buttonText,\n}: MeetingCardProps) =\u003e {\n  const { toast } = useToast();\n\n  return (\n    \u003csection className=\"flex min-h-[258px] w-full flex-col justify-between rounded-[14px] bg-dark-1 px-5 py-8 xl:max-w-[568px]\"\u003e\n      \u003carticle className=\"flex flex-col gap-5\"\u003e\n        \u003cImage src={icon} alt=\"upcoming\" width={28} height={28} /\u003e\n        \u003cdiv className=\"flex justify-between\"\u003e\n          \u003cdiv className=\"flex flex-col gap-2\"\u003e\n            \u003ch1 className=\"text-2xl font-bold\"\u003e{title}\u003c/h1\u003e\n            \u003cp className=\"text-base font-normal\"\u003e{date}\u003c/p\u003e\n          \u003c/div\u003e\n        \u003c/div\u003e\n      \u003c/article\u003e\n      \u003carticle className={cn(\"flex justify-center relative\", {})}\u003e\n        \u003cdiv className=\"relative flex w-full max-sm:hidden\"\u003e\n          {avatarImages.map((img, index) =\u003e (\n            \u003cImage\n              key={index}\n              src={img}\n              alt=\"attendees\"\n              width={40}\n              height={40}\n              className={cn(\"rounded-full\", { absolute: index \u003e 0 })}\n              style={{ top: 0, left: index * 28 }}\n            /\u003e\n          ))}\n          \u003cdiv className=\"flex-center absolute left-[136px] size-10 rounded-full border-[5px] border-dark-3 bg-dark-4\"\u003e\n            +5\n          \u003c/div\u003e\n        \u003c/div\u003e\n        {!isPreviousMeeting \u0026\u0026 (\n          \u003cdiv className=\"flex gap-2\"\u003e\n            \u003cButton onClick={handleClick} className=\"rounded bg-blue-1 px-6\"\u003e\n              {buttonIcon1 \u0026\u0026 (\n                \u003cImage src={buttonIcon1} alt=\"feature\" width={20} height={20} /\u003e\n              )}\n              \u0026nbsp; {buttonText}\n            \u003c/Button\u003e\n            \u003cButton\n              onClick={() =\u003e {\n                navigator.clipboard.writeText(link);\n                toast({\n                  title: \"Link Copied\",\n                });\n              }}\n              className=\"bg-dark-4 px-6\"\n            \u003e\n              \u003cImage\n                src=\"/icons/copy.svg\"\n                alt=\"feature\"\n                width={20}\n                height={20}\n              /\u003e\n              \u0026nbsp; Copy Link\n            \u003c/Button\u003e\n          \u003c/div\u003e\n        )}\n      \u003c/article\u003e\n    \u003c/section\u003e\n  );\n};\n\nexport default MeetingCard;\n```\n\n\u003c/details\u003e\n\n## \u003ca name=\"links\"\u003e🔗 Links\u003c/a\u003e\n\nPublic assets used in the project can be found [here](https://drive.google.com/file/d/1ofTpWii_sCIdJ14uQ431xWVXpYgjtQ8Q/view?usp=sharing)\n\n## \u003ca name=\"more\"\u003e🚀 More\u003c/a\u003e\n\n**Advance your skills with Next.js Pro Course**\n\nEnjoyed creating this project? Dive deeper into our PRO courses for a richer learning experience. They're packed with detailed explanations, cool features, and exercises to boost your skills. Give it a go!\n\n\u003ca href=\"https://www.jsmastery.pro/ultimate-next-course\" target=\"_blank\"\u003e\n\u003cimg src=\"https://i.ibb.co/804sPK6/Image-720.png\" alt=\"Project Banner\"\u003e\n\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadrianhajdin%2Fzoom-clone","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadrianhajdin%2Fzoom-clone","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadrianhajdin%2Fzoom-clone/lists"}