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

feat: user display names #144

Merged
merged 11 commits into from
May 4, 2023
30 changes: 0 additions & 30 deletions components/AuthForm.tsx

This file was deleted.

6 changes: 4 additions & 2 deletions components/ItemSummary.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright 2023 the Deno authors. All rights reserved. MIT license.
import type { Item } from "@/utils/db.ts";
import type { Item, User } from "@/utils/db.ts";

export function pluralize(unit: number, label: string) {
return unit === 1 ? `${unit} ${label}` : `${unit} ${label}s`;
Expand All @@ -15,6 +15,7 @@ export function timeAgo(time: number | Date) {

export interface ItemSummaryProps {
item: Item;
user: User;
commentsCount: number;
}

Expand All @@ -31,7 +32,8 @@ export default function ItemSummary(props: ItemSummaryProps) {
</span>
</div>
<div class="text-gray-500">
{pluralize(props.item.score, "point")} by {props.item.userId}{" "}
{pluralize(props.item.score, "point")} by{" "}
{props.user.displayName || props.item.userId}{" "}
{timeAgo(new Date(props.item.createdAt))} ago •{" "}
<a href={`/item/${props.item.id}`}>
{pluralize(props.commentsCount, "comment")}
Expand Down
8 changes: 8 additions & 0 deletions routes/account/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ export default function AccountPage(props: PageProps<AccountPageData>) {
</div>
)}
<ul class="divide-y">
<li class="py-4">
<p>
<strong>Display name</strong>
</p>
<p>
{props.data.user.displayName}
</p>
</li>
<li class="py-4">
<p>
<strong>Email</strong>
Expand Down
13 changes: 11 additions & 2 deletions routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,28 @@ import Layout from "@/components/Layout.tsx";
import Head from "@/components/Head.tsx";
import type { State } from "./_middleware.ts";
import ItemSummary from "@/components/ItemSummary.tsx";
import { getAllItems, getItemCommentsCount, type Item } from "@/utils/db.ts";
import {
getAllItems,
getItemCommentsCount,
getUsersByIds,
type Item,
type User,
} from "@/utils/db.ts";

interface HomePageData extends State {
users: User[];
items: Item[];
commentsCounts: number[];
}

export const handler: Handlers<HomePageData, State> = {
async GET(_req, ctx) {
const items = await getAllItems();
const users = await getUsersByIds(items.map((item) => item.userId));
const commentsCounts = await Promise.all(
items.map((item) => getItemCommentsCount(item.id)),
);
return ctx.render({ ...ctx.state, items, commentsCounts });
return ctx.render({ ...ctx.state, items, commentsCounts, users });
},
};

Expand All @@ -32,6 +40,7 @@ export default function HomePage(props: PageProps<HomePageData>) {
<ItemSummary
item={item}
commentsCount={props.data.commentsCounts[index]}
user={props.data.users[index]}
/>
))}
</div>
Expand Down
29 changes: 24 additions & 5 deletions routes/item/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,21 @@ import {
} from "@/utils/constants.ts";
import { timeAgo } from "@/components/ItemSummary.tsx";
import {
Comment,
type Comment,
createComment,
getCommentsByItem,
getItemById,
Item,
getUserById,
getUsersByIds,
type Item,
type User,
} from "@/utils/db.ts";

interface ItemPageData extends State {
user: User;
item: Item;
comments: Comment[];
commentsUsers: User[];
}

export const handler: Handlers<ItemPageData, State> = {
Expand All @@ -33,8 +38,18 @@ export const handler: Handlers<ItemPageData, State> = {
}

const comments = await getCommentsByItem(id);
const commentsUsers = await getUsersByIds(
comments.map((comment) => comment.userId),
);
iuioiua marked this conversation as resolved.
Show resolved Hide resolved
const user = await getUserById(item.userId);

return ctx.render({ ...ctx.state, item, comments });
return ctx.render({
...ctx.state,
item,
comments,
user: user!,
commentsUsers,
});
},
async POST(req, ctx) {
if (!ctx.state.session) {
Expand Down Expand Up @@ -76,11 +91,15 @@ export default function ItemPage(props: PageProps<ItemPageData>) {
<ItemSummary
item={props.data.item}
commentsCount={props.data.comments.length}
user={props.data.user}
/>
<div class="divide-y">
{props.data.comments.map((comment) => (
{props.data.comments.map((comment, index) => (
<div class="py-4">
<p>{comment.userId}</p>
<p>
{props.data.commentsUsers[index].displayName ||
comment.userId}
</p>
<p class="text-gray-500">
{timeAgo(new Date(comment.createdAt))} ago
</p>
Expand Down
22 changes: 20 additions & 2 deletions routes/login/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
import type { Handlers, PageProps } from "$fresh/server.ts";
import Logo from "@/components/Logo.tsx";
import Head from "@/components/Head.tsx";
import AuthForm from "@/components/AuthForm.tsx";
import OAuthLoginButton from "@/components/OAuthLoginButton.tsx";
import { NOTICE_STYLES } from "@/utils/constants.ts";
import { REDIRECT_PATH_AFTER_LOGIN } from "@/utils/constants.ts";
import type { State } from "@/routes/_middleware.ts";
import { BUTTON_STYLES, INPUT_STYLES } from "@/utils/constants.ts";

// deno-lint-ignore no-explicit-any
export const handler: Handlers<any, State> = {
Expand Down Expand Up @@ -74,7 +74,25 @@ export default function LoginPage(props: PageProps) {
{errorMessage && POSSIBLE_ERROR_MESSAGES.has(errorMessage) && (
<div class={NOTICE_STYLES}>{errorMessage}</div>
)}
<AuthForm type="Login" />
<form method="POST" class="space-y-4">
<input
placeholder="Email"
name="email"
type="email"
required
class={INPUT_STYLES}
/>
<input
placeholder="Password"
name="password"
type="password"
required
class={INPUT_STYLES}
/>
<button type="submit" class={`${BUTTON_STYLES} w-full`}>
Login
</button>
</form>
<hr class="my-4" />
<OAuthLoginButton
provider="github"
Expand Down
34 changes: 32 additions & 2 deletions routes/signup.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2023 the Deno authors. All rights reserved. MIT license.
import type { PageProps } from "$fresh/server.ts";
import Head from "@/components/Head.tsx";
import AuthForm from "@/components/AuthForm.tsx";
import Logo from "@/components/Logo.tsx";
import OAuthLoginButton from "@/components/OAuthLoginButton.tsx";
import { NOTICE_STYLES } from "@/utils/constants.ts";
Expand All @@ -10,11 +9,13 @@ import { REDIRECT_PATH_AFTER_LOGIN } from "@/utils/constants.ts";
import type { State } from "./_middleware.ts";
import { stripe } from "@/utils/payments.ts";
import { createUser } from "@/utils/db.ts";
import { BUTTON_STYLES, INPUT_STYLES } from "@/utils/constants.ts";

// deno-lint-ignore no-explicit-any
export const handler: Handlers<any, State> = {
async POST(req, ctx) {
const form = await req.formData();
const displayName = form.get("display_name") as string;
const email = form.get("email") as string;
const password = form.get("password") as string;

Expand All @@ -32,6 +33,7 @@ export const handler: Handlers<any, State> = {

const { id } = await stripe.customers.create({ email });
await createUser({
displayName,
id: data.user!.id,
stripeCustomerId: id,
});
Expand Down Expand Up @@ -71,7 +73,35 @@ export default function SignupPage(props: PageProps) {
{errorMessage && POSSIBLE_ERROR_MESSAGES.has(errorMessage) && (
<div class={NOTICE_STYLES}>{errorMessage}</div>
)}
<AuthForm type="Signup" />
<form
method="POST"
class="space-y-4"
>
<input
placeholder="Display name"
name="display_name"
type="text"
required
class={INPUT_STYLES}
/>
<input
placeholder="Email"
name="email"
type="email"
required
class={INPUT_STYLES}
/>
<input
placeholder="Password"
name="password"
type="password"
required
class={INPUT_STYLES}
/>
<button type="submit" class={`${BUTTON_STYLES} w-full`}>
Signup
</button>
</form>
<hr class="my-4" />
<OAuthLoginButton
provider="github"
Expand Down
13 changes: 12 additions & 1 deletion utils/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export async function getItemCommentsCount(itemId: string) {
interface InitUser {
id: string;
stripeCustomerId: string;
displayName: string;
}

export interface User extends InitUser {
Expand Down Expand Up @@ -164,10 +165,20 @@ export async function setUserSubscription(
}
}

export async function getUsersByIds(ids: string[]) {
const keys = ids.map((id) => ["users", id]);
const res = await kv.getMany<User[]>(keys);
return res.map((entry) => entry.value!);
}

export async function getOrCreateUser(id: string, email: string) {
const user = await getUserById(id);
if (user) return user;

const customer = await stripe.customers.create({ email });
return await createUser({ id, stripeCustomerId: customer.id });
return await createUser({
id,
stripeCustomerId: customer.id,
displayName: "",
});
}