Skip to content

Commit

Permalink
Add Files - initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Tanmay-312 committed Aug 13, 2024
0 parents commit 4d325a3
Show file tree
Hide file tree
Showing 78 changed files with 9,913 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
36 changes: 36 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
13 changes: 13 additions & 0 deletions .hintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": [
"development"
],
"hints": {
"axe/name-role-value": [
"default",
{
"button-name": "off"
}
]
}
}
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
24 changes: 24 additions & 0 deletions actions/stream.actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use server';

import { currentUser } from '@clerk/nextjs/server';
import { StreamClient } from '@stream-io/node-sdk';

const STREAM_API_KEY = process.env.NEXT_PUBLIC_STREAM_API_KEY;
const STREAM_API_SECRET = process.env.STREAM_SECRET_KEY;

export const tokenProvider = async () => {
const user = await currentUser();

if (!user) throw new Error('User is not authenticated');
if (!STREAM_API_KEY) throw new Error('Stream API key secret is missing');
if (!STREAM_API_SECRET) throw new Error('Stream API secret is missing');

const streamClient = new StreamClient(STREAM_API_KEY, STREAM_API_SECRET);

const expirationTime = Math.floor(Date.now() / 1000) + 3600;
const issuedAt = Math.floor(Date.now() / 1000) - 60;

const token = streamClient.createToken(user.id, expirationTime, issuedAt);

return token;
};
9 changes: 9 additions & 0 deletions app/(auth)/sign-in/[[...sign-in]]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { SignIn } from '@clerk/nextjs';

export default function SignInPage() {
return (
<main className="flex h-screen w-full items-center justify-center">
<SignIn />
</main>
);
}
9 changes: 9 additions & 0 deletions app/(auth)/sign-up/[[...sign-up]]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { SignUp } from '@clerk/nextjs';

export default function SignUpPage() {
return (
<main className="flex h-screen w-full items-center justify-center">
<SignUp />
</main>
);
}
28 changes: 28 additions & 0 deletions app/(root)/(home)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Metadata } from 'next';
import { ReactNode } from 'react';

import Navbar from '@/components/Navbar';
import Sidebar from '@/components/Sidebar';

export const metadata: Metadata = {
title: 'ZMeet',
description: 'A workspace for your team, powered by Stream Chat and Clerk.',
};

const RootLayout = ({ children }: Readonly<{children: ReactNode}>) => {
return (
<main className="relative">
<Navbar />

<div className="flex">
<Sidebar />

<section className="flex min-h-screen flex-1 flex-col px-6 pb-6 pt-28 max-md:pb-14 sm:px-14">
<div className="w-full">{children}</div>
</section>
</div>
</main>
);
};

export default RootLayout;
28 changes: 28 additions & 0 deletions app/(root)/(home)/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import MeetingTypeList from '@/components/MeetingTypeList';

const Home = () => {
const now = new Date();

const time = now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
const date = (new Intl.DateTimeFormat('en-US', { dateStyle: 'full' })).format(now);

return (
<section className="flex size-full flex-col gap-5 text-white">
<div className="h-[303px] w-full rounded-[20px] bg-hero bg-cover">
<div className="flex h-full flex-col justify-between max-md:px-5 max-md:py-8 lg:p-11">
<h2 className="glassmorphism max-w-[600px] rounded py-2 text-center text-base font-normal">
Connect effortlessly with ZMeet, your seamless online meeting solution.
</h2>
<div className="flex flex-col gap-2">
<h1 className="text-4xl font-extrabold lg:text-7xl">{time}</h1>
<p className="text-lg font-medium text-sky-1 lg:text-2xl">{date}</p>
</div>
</div>
</div>

<MeetingTypeList />
</section>
);
};

export default Home;
86 changes: 86 additions & 0 deletions app/(root)/(home)/personal-room/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"use client";

import { useUser } from "@clerk/nextjs";
import { useStreamVideoClient } from "@stream-io/video-react-sdk";
import { useRouter } from "next/navigation";

import { useGetCallById } from "@/hooks/useGetCallById";
import { Button } from "@/components/ui/button";
import { useToast } from "@/components/ui/use-toast";

const Table = ({
title,
description,
}: {
title: string;
description: string;
}) => {
return (
<div className="flex flex-col items-start gap-2 xl:flex-row">
<h1 className="text-base font-medium text-sky-1 lg:text-xl xl:min-w-32">
{title}:
</h1>
<h1 className="truncate text-sm font-bold max-sm:max-w-[320px] lg:text-xl">
{description}
</h1>
</div>
);
};

const PersonalRoom = () => {
const router = useRouter();
const { user } = useUser();
const client = useStreamVideoClient();
const { toast } = useToast();

const meetingId = user?.id;

const { call } = useGetCallById(meetingId!);

const startRoom = async () => {
if (!client || !user) return;

const newCall = client.call("default", meetingId!);

if (!call) {
await newCall.getOrCreate({
data: {
starts_at: new Date().toISOString(),
},
});
}

router.push(`/meeting/${meetingId}?personal=true`);
};

const meetingLink = `${process.env.NEXT_PUBLIC_BASE_URL}/meeting/${meetingId}?personal=true`;

return (
<section className="flex size-full flex-col gap-10 text-white">
<h1 className="text-xl font-bold lg:text-3xl">Personal Meeting Room</h1>
<div className="flex w-full flex-col gap-8 xl:max-w-[900px]">
<Table title="Topic" description={`${user?.username}'s Meeting Room`} />
<Table title="Meeting ID" description={meetingId!} />
<Table title="Invite Link" description={meetingLink} />
</div>
<div className="flex gap-5">
<Button className="bg-blue-1" onClick={startRoom}>
Start Meeting
</Button>
<Button
className="bg-dark-3"
onClick={() => {
navigator.clipboard.writeText(meetingLink);
toast({
title: "Link Copied",
});
}}
>
Copy Invitation
</Button>
</div>
</section>
);
};

export default PersonalRoom;
13 changes: 13 additions & 0 deletions app/(root)/(home)/previous/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import CallList from "@/components/CallList";

const PreviousPage = () => {
return (
<section className="flex size-full flex-col gap-10 text-white">
<h1 className="text-3xl font-bold">Previous Calls</h1>

<CallList type="ended" />
</section>
);
};

export default PreviousPage;
13 changes: 13 additions & 0 deletions app/(root)/(home)/recordings/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import CallList from '@/components/CallList';

const PreviousPage = () => {
return (
<section className="flex size-full flex-col gap-10 text-white">
<h1 className="text-3xl font-bold">Recordings</h1>

<CallList type="recordings" />
</section>
);
};

export default PreviousPage;
13 changes: 13 additions & 0 deletions app/(root)/(home)/upcoming/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import CallList from '@/components/CallList';

const UpcomingPage = () => {
return (
<section className="flex size-full flex-col gap-10 text-white">
<h1 className="text-3xl font-bold">Upcoming Meeting</h1>

<CallList type="upcoming" />
</section>
);
};

export default UpcomingPage;
13 changes: 13 additions & 0 deletions app/(root)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ReactNode } from 'react';

import StreamVideoProvider from '@/providers/StreamClientProvider';

const RootLayout = ({ children }: Readonly<{ children: ReactNode }>) => {
return (
<main>
<StreamVideoProvider>{children}</StreamVideoProvider>
</main>
);
};

export default RootLayout;
49 changes: 49 additions & 0 deletions app/(root)/meeting/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use client';

import { useState } from 'react';
import { useUser } from '@clerk/nextjs';
import { StreamCall, StreamTheme } from '@stream-io/video-react-sdk';
import { useParams } from 'next/navigation';
import { Loader } from 'lucide-react';

import { useGetCallById } from '@/hooks/useGetCallById';
import Alert from '@/components/Alert';
import MeetingSetup from '@/components/MeetingSetup';
import MeetingRoom from '@/components/MeetingRoom';

const MeetingPage = () => {
const { id } = useParams();
const { isLoaded, user } = useUser();
const { call, isCallLoading } = useGetCallById(id);
const [isSetupComplete, setIsSetupComplete] = useState(false);

if (!isLoaded || isCallLoading) return <Loader />;

if (!call) return (
<p className="text-center text-3xl font-bold text-white">
Call Not Found
</p>
);

// get more info about custom call type: https://getstream.io/video/docs/react/guides/configuring-call-types/
const notAllowed = call.type === 'invited' && (!user || !call.state.members.find((m) => m.user.id === user.id));

if (notAllowed) return <Alert title="You are not allowed to join this meeting" />;

return (
<main className="h-screen w-full">
<StreamCall call={call}>
<StreamTheme>

{!isSetupComplete ? (
<MeetingSetup setIsSetupComplete={setIsSetupComplete} />
) : (
<MeetingRoom />
)}
</StreamTheme>
</StreamCall>
</main>
);
};

export default MeetingPage;
Loading

0 comments on commit 4d325a3

Please sign in to comment.