Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Email to Sign / In and Sign Up Page, Settings Page, User can delete all Messages #232

Merged
merged 42 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
5fc3802
- Version
Gamius00 Jun 2, 2024
888d2c1
Merge remote-tracking branch 'origin/main'
Gamius00 Jun 4, 2024
344d475
Merge remote-tracking branch 'origin/main'
Gamius00 Jun 7, 2024
f2bc7eb
Merge remote-tracking branch 'origin/main'
Gamius00 Jun 9, 2024
90d9a49
Merge remote-tracking branch 'origin/main'
Gamius00 Jun 15, 2024
e14987e
- Fixed Syntax chnaged unused creationtime
Gamius00 Jun 15, 2024
681136b
- Fixed Error
Gamius00 Jun 15, 2024
5376643
- Changed async Func to normal Func
Gamius00 Jun 15, 2024
4bd0c3e
- Added profile pages
Gamius00 Jun 17, 2024
ef498bf
Merge branch 'main' into profile-redesign
FleetAdmiralJakob Jun 18, 2024
54fbcb5
- Email Update
Gamius00 Jun 18, 2024
415a4b9
- Email Update
Gamius00 Jun 19, 2024
7cecf67
- Added BackArrow
Gamius00 Jun 19, 2024
69d4f4d
Merge remote-tracking branch 'origin/main'
Gamius00 Jun 19, 2024
7d4b05d
Merge branch 'refs/heads/main' into profile-redesign
Gamius00 Jun 19, 2024
a9a8690
- Merged Main Branch into Profile
Gamius00 Jun 19, 2024
82b63a6
Merge branch 'main' into profile-redesign
FleetAdmiralJakob Jun 19, 2024
10f1d1c
Merge branch 'main' into profile-redesign
FleetAdmiralJakob Jun 22, 2024
5db507f
- Added a deleteAllMessages request message
Gamius00 Jul 2, 2024
091b23b
Merge remote-tracking branch 'origin/contrasts' into delete-all-messages
Gamius00 Jul 2, 2024
465f481
- Deleted unused import
Gamius00 Jul 2, 2024
d7b020d
- Changed typename User to Message
Gamius00 Jul 2, 2024
ebe38ca
Merge branch 'main' into contrasts
Gamius00 Jul 2, 2024
7ca5f63
User can change the Password
Gamius00 Jul 3, 2024
a8eaff9
Merge branch 'main' into contrasts
FleetAdmiralJakob Jul 3, 2024
6aa8461
Fixed Error: Uncaught Error: Update on nonexistent document ID jh765j…
Gamius00 Jul 3, 2024
59c9b7c
Added sonnertoast if the password change
Gamius00 Jul 3, 2024
53da4ef
Merge branch 'main' into profile-redesign
Gamius00 Jul 3, 2024
dd764f7
- Added Save (Firstname, Lastname)
Gamius00 Jul 6, 2024
f9bbaa1
Merge branch 'main' into profile-redesign
FleetAdmiralJakob Jul 7, 2024
411310b
- Updated reviewed things by jakob
Gamius00 Jul 7, 2024
d3a0067
Merge remote-tracking branch 'origin/profile-redesign' into profile-r…
Gamius00 Jul 7, 2024
98be76d
Merge branch 'main' into profile-redesign
FleetAdmiralJakob Jul 8, 2024
52476a6
- Added This feature is not available yet
Gamius00 Jul 9, 2024
c43a2ac
Merge remote-tracking branch 'origin/profile-redesign' into profile-r…
Gamius00 Jul 9, 2024
39e3aa4
Merge branch 'refs/heads/delete-all-messages' into profile-redesign
Gamius00 Jul 10, 2024
dc28a31
- Update UserData in Convex
Gamius00 Jul 10, 2024
2a1bb35
- Sent Date
Gamius00 Jul 11, 2024
d9963fe
Merge branch 'main' into profile-redesign
FleetAdmiralJakob Jul 11, 2024
9a7bbb8
- Changed Reviewed things & new pnpm version
Gamius00 Aug 1, 2024
d26d587
- Added a 0 to the date string in the messages
Gamius00 Aug 1, 2024
3756ac6
Merge branch 'main' into profile-redesign
FleetAdmiralJakob Aug 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions convex/chats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export const initialConvexSetup = mutation({
username: identity.nickname,
clerkId: identity.tokenIdentifier,
firstName: identity.givenName,
email: identity.email,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Set the value of the emailfield

lastName: identity.familyName,
})
.get();
Expand Down
108 changes: 108 additions & 0 deletions convex/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,56 @@ export const getMessages = query({
},
});

export const createDeleteRequest = mutation({
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the mutation for creating a delete all messages request

args: { chatId: v.string() },
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();

if (identity === null) {
console.error("Unauthenticated call to mutation");
return null;
}

const convexUser = await ctx
.table("users")
.get("clerkId", identity.tokenIdentifier);

const parsedChatId = ctx.table("privateChats").normalizeId(args.chatId);

if (!parsedChatId) {
throw new ConvexError("chatId was invalid");
}

if (!convexUser) {
throw new ConvexError(
"Mismatch between Clerk and Convex. This is an error by us.",
);
}

const usersInChat = await ctx
.table("privateChats")
.getX(parsedChatId)
.edge("users");

if (
!usersInChat.some((user) => user.clerkId === identity.tokenIdentifier)
) {
throw new ConvexError(
"UNAUTHORIZED REQUEST: User tried to send a message in a chat in which he is not in.",
);
}

await ctx.table("messages").insert({
userId: convexUser._id,
privateChatId: parsedChatId,
content: "",
type: "request",
deleted: false,
readBy: [convexUser._id],
});
},
});

export const createMessage = mutation({
args: { chatId: v.string(), content: v.string() },
handler: async (ctx, args) => {
Expand Down Expand Up @@ -84,12 +134,62 @@ export const createMessage = mutation({
userId: convexUser._id,
privateChatId: parsedChatId,
content: args.content.trim(),
type: "message",
deleted: false,
readBy: [convexUser._id],
});
},
});

export const deleteAllMessagesInChat = mutation({
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the mutation for delete all messages

args: { chatId: v.string() },
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();

if (identity === null) {
console.error("Unauthenticated call to mutation");
return null;
}

const parsedChatId = ctx.table("privateChats").normalizeId(args.chatId);

if (!parsedChatId) {
throw new ConvexError("chatId was invalid");
}

const chat = ctx.table("privateChats").getX(parsedChatId);
const messagesInChat = await chat.edge("messages");

for (const message of messagesInChat) {
await message.delete();
}
},
});

export const rejectRequest = mutation({
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the reject request mutation

args: { messageId: v.string(), chatId: v.string() },
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();

if (identity === null) {
console.error("Unauthenticated call to mutation");
return null;
}

const parsedMessageId = ctx.table("messages").normalizeId(args.messageId);

if (!parsedMessageId) {
throw new ConvexError("chatId was invalid");
}

const message = await ctx.table("messages").getX(parsedMessageId);

await message.patch({
type: "rejected",
});
},
});

export const deleteMessage = mutation({
args: { messageId: v.string(), chatId: v.string() },
handler: async (ctx, args) => {
Expand Down Expand Up @@ -145,6 +245,12 @@ export const markMessageRead = mutation({
);
}

const message = await ctx.table("messages").get(args.messageId);

if (!message) {
return null;
}

await ctx
.table("messages")
.getX(args.messageId)
Expand All @@ -153,5 +259,7 @@ export const markMessageRead = mutation({
add: [convexUser._id],
},
});

return { success: true };
},
});
2 changes: 2 additions & 0 deletions convex/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const schema = defineEntSchema({
.field("clerkId", v.string(), { unique: true })
.field("username", v.string(), { unique: true })
.field("firstName", v.optional(v.string()))
.field("email", v.optional(v.string()))
.field("lastName", v.optional(v.string()))
.edges("privateChats")
.edges("messages", { ref: true })
Expand All @@ -22,6 +23,7 @@ const schema = defineEntSchema({

messages: defineEnt({})
.field("content", v.string())
.field("type", v.string(), { default: "message" })
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the type of a message.
I need a difference between the normal messages and the request messages

.field("deleted", v.boolean(), { default: false })
.edge("privateChat")
.edge("user")
Expand Down
42 changes: 40 additions & 2 deletions convex/users.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { query } from "./lib/functions";
import { ConvexError } from "convex/values";
import { mutation, query } from "./lib/functions";
import { v } from "convex/values";

export const getUserData = query({
handler: async (ctx) => {
Expand All @@ -13,3 +13,41 @@ export const getUserData = query({
return ctx.table("users").getX("clerkId", identity.tokenIdentifier);
},
});

export const updateUserData = mutation({
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here I update the user data (firstname, lastname, email)

args: {
data: v.object({
firstName: v.optional(v.string()),
lastName: v.optional(v.string()),
email: v.optional(v.string()),
}),
},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();

if (identity === null) {
console.error("Unauthenticated call to mutation");
return null;
}

const user = ctx.table("users").getX("clerkId", identity.tokenIdentifier);

if (args.data.email) {
await user.patch({
email: args.data.email,
});
}

if (args.data.lastName) {
await user.patch({
lastName: args.data.lastName,
});
}

if (args.data.firstName) {
await user.patch({
firstName: args.data.firstName,
});
}
},
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"sonner": "^1.5.0",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
"zod": "^3.23.8"
"zod": "3.23.8"

Choose a reason for hiding this comment

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

Make it as it was before (^^^^^^)

},
"devDependencies": {
"@total-typescript/ts-reset": "^0.5.1",
Expand Down
2 changes: 1 addition & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 30 additions & 4 deletions src/app/(auth)/sign-up/signup-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from "~/components/ui/form";
import { Input } from "~/components/ui/input";
import React, { useEffect } from "react";
import { formSchema } from "~/lib/validators";
import { formSchemaSignUp } from "~/lib/validators";
import { useSignIn } from "@clerk/nextjs";
import { useRouter } from "next/navigation";
import { cn } from "~/lib/utils";
Expand All @@ -38,8 +38,8 @@ export function SignUpForm() {
const { isLoading, isAuthenticated } = useConvexAuth();
const router = useRouter();

const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
const form = useForm<z.infer<typeof formSchemaSignUp>>({
resolver: zodResolver(formSchemaSignUp),
defaultValues: {
username: "",
usernameId: "",
Expand All @@ -62,7 +62,7 @@ export function SignUpForm() {
}
}, [initialConvexSetup, isAuthenticated, router, signUpComplete]);

async function onSubmit(values: z.infer<typeof formSchema>) {
async function onSubmit(values: z.infer<typeof formSchemaSignUp>) {
if (isAuthenticated || isLoading) {
// TODO: Make a toast or something to tell the user has to sign out first
return;
Expand All @@ -89,6 +89,15 @@ export function SignUpForm() {
return;
}

if (parsedResponseBody.data?.statusText === "email_is_taken") {
form.setError("email", {
message: "Email is already taken. Please choose another.",
});

setFormIsLoading(false);
return;
}

if (parsedResponseBody.data?.statusText === "form_password_pwned") {
form.setError("password", {
message:
Expand Down Expand Up @@ -244,6 +253,23 @@ export function SignUpForm() {
>
This is optional, so you can stay anonymous.
</span>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem className="flex-2">
<FormLabel>Email</FormLabel>
<FormControl>
<Input placeholder="email" type="text" {...field} />
</FormControl>
<FormDescription>
This is optional, but if you forgot your password, we can send
you an email.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="password"
Expand Down
13 changes: 12 additions & 1 deletion src/app/(internal-sites)/chats/[chatId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export default function Page({ params }: { params: { chatId: string } }) {
_creationTime: now,
content,
deleted: false,
type: "message",
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the normal type of any message that is not a request

privateChatId: chatId,
from: userInfo.data,
readBy: [userInfo.data],
Expand Down Expand Up @@ -203,6 +204,13 @@ export default function Page({ params }: { params: { chatId: string } }) {
setInputValue("");
scrollToBottom(true);
}

const createDeleteRequest = useMutation(api.messages.createDeleteRequest);

const createMessageRequestHandler = (chatId: string) => async () => {
await createDeleteRequest({ chatId });
};

const [menuActive, setMenuActive] = useState(false);

const menuClick = () => {
Expand Down Expand Up @@ -234,7 +242,10 @@ export default function Page({ params }: { params: { chatId: string } }) {
className="relative flex flex-col"
>
<DevMode className="top-20 z-10">
chatId: {params.chatId}
<button onClick={createMessageRequestHandler(params.chatId)}>
Delete Chat Request
</button>
<p>chatId: {params.chatId}</p>
<div onClick={() => devMode$.set(false)}>Disable dev mode</div>
</DevMode>
<div className="flex h-20 w-full items-center justify-between bg-primary py-6">
Expand Down
5 changes: 5 additions & 0 deletions src/app/(internal-sites)/profile/chats/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const ChatsPage = () => {
return <div className="ml-24">Chats</div>;
};

export default ChatsPage;
5 changes: 5 additions & 0 deletions src/app/(internal-sites)/profile/notification/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const NotificationPage = () => {
return <div className="ml-24">Notification</div>;
};

export default NotificationPage;
Loading