Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
usirin committed Aug 1, 2023
1 parent 3e3636d commit d375fe4
Show file tree
Hide file tree
Showing 15 changed files with 1,019 additions and 81 deletions.
1 change: 1 addition & 0 deletions apps/gql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"dependencies": {
"@graphql-tools/schema": "9.0.19",
"@kampus/gql-utils": "*",
"@kampus/next-auth": "^0.0.0",
"@kampus/prisma": "*",
"@kampus/sozluk-content": "*",
"@kampus/std": "*",
Expand Down
24 changes: 12 additions & 12 deletions apps/gql/schema/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,7 @@ type PanoPost implements Node {
content: String
createdAt: DateTime!
owner: User
comments(
after: String
before: String
first: Int
last: Int
): PanoCommentConnection
comments(after: String, before: String, first: Int, last: Int): PanoCommentConnection
}

type PanoPostConnection {
Expand All @@ -119,12 +114,7 @@ type PanoComment implements Node {
owner: User
post: PanoPost
parent: PanoComment
comments(
after: String
before: String
first: Int
last: Int
): PanoCommentConnection
comments(after: String, before: String, first: Int, last: Int): PanoCommentConnection
createdAt: DateTime!
}

Expand All @@ -139,3 +129,13 @@ type PanoCommentEdge {
cursor: String!
node: PanoComment
}

type Mutation {
createPanoPost(input: CreateTodoInput!): CreateTodoPayload
}

input CreateTodoInput {
title: String!
content: String
url: String
}
85 changes: 56 additions & 29 deletions apps/kampus/app/pano/features/post-list/PostItem.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,83 @@
"use client";

import NextLink from "next/link";
import { graphql, useFragment } from "react-relay";

import { cn } from "@kampus/ui-next/utils";

import { MoreOptionsDropdown } from "./MoreOptions";
import { TimeAgo } from "~/../../packages/ui";
import { type PostItem_post$key } from "./__generated__/PostItem_post.graphql";
import { UpvoteButton } from "./PostUpvoteButton";

type Post = {
__typename?: "PanoPost";
content: string;
createdAt: string;
id: string;
owner: string;
title: string;
url: string;
};

type PostItemProps = {
post: Post;
showContent?: boolean;
};
// import { MoreOptionsDropdown } from "./MoreOptions";

interface LinkProps {
href: string;
title: string;
children: string;
className?: string;
}

const Link = ({ href, title, className }: LinkProps) => {
const Link = ({ href, children: title, className }: LinkProps) => {
return (
<NextLink className={cn("text-muted-foreground hover:underline", className)} href={href}>
<NextLink className={cn("hover:underline", className)} href={href}>
{title}
</NextLink>
);
};

const usePanoPostFragment = (key: PostItem_post$key | null) =>
useFragment(
graphql`
fragment PostItem_post on PanoPost {
id
title
content
url
createdAt
id
site
owner {
username
}
}
`,
key
);

interface PostItemProps {
post: PostItem_post$key;
showContent?: boolean;
}

export const PostItem = (props: PostItemProps) => {
const post = usePanoPostFragment(props.post);

if (!post) {
return null;
}

return (
<div className="mr-1 flex h-full gap-1 border-l-2">
<div className="ml-1 flex h-full">
<UpvoteButton upvoteCount={5} isUpvoted={false} disabled={false} isVoting={false} />
</div>
<section className="flex h-full items-center gap-2 rounded">
<UpvoteButton upvoteCount={5} isUpvoted={false} disabled={false} isVoting={false} />

<div className="flex w-full flex-col justify-center">
<div className="flex items-center gap-1 align-baseline">
<Link title={props.post.title} href={props.post.url} />
<Link className="text-sm" title="wow.sh" href={props.post.url} />
<Link className="font-semibold" href={post.url ?? ""}>
{post.title}
</Link>
<Link className="text-sm" href={post.url ?? ""}>
{post.site ?? ""}
</Link>
</div>
<div className="flex items-center gap-1 text-sm">
<div>@{props.post.owner} |</div>
<div>{<Link title="0 yorum" href={`/pano/post/${props.post.id}/`} />} |</div>
<div>{props.post.createdAt} |</div>
<MoreOptionsDropdown post={props.post} shareUrl={props.post.url} />
<div>@{post.owner?.username} |</div>
<div>
<Link href={`/pano/post/${post.id}`}>0 yorum</Link> |
</div>
<TimeAgo date={new Date(post.createdAt as string)} />
</div>
</div>
</div>
</section>
);
};
8 changes: 3 additions & 5 deletions apps/kampus/app/pano/features/post-list/PostUpvoteButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@ export const UpvoteButton = (props: UpvoteProps) => {
const combinedStyle = cn(upvoteStyle, opacity);

return (
<Button className="flex h-full items-center pt-3" variant="ghost">
<div className="flex flex-col items-center justify-center">
<Triangle className={combinedStyle} size={12} />
{`${props.upvoteCount}`}
</div>
<Button className="flex h-full flex-col" variant="outline">
<Triangle className={combinedStyle} size={12} />
{props.upvoteCount}
</Button>
);
};

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

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 0 additions & 1 deletion apps/kampus/app/pano/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ import { DEFAULT_FILTER_PATH } from "~/app/pano/features/post-filter/utils";

export default function PanoHome() {
redirect(DEFAULT_FILTER_PATH);
return <div>Just redirecting</div>;
}
85 changes: 85 additions & 0 deletions apps/kampus/app/pano/posts/AllPosts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { useCallback } from "react";
import { graphql, usePaginationFragment } from "react-relay";

import { Button } from "@kampus/ui-next";

import { PostItem } from "../features/post-list/PostItem";
import { type AllPostsFragment$key } from "./__generated__/AllPostsFragment.graphql";
import { type AllPostsPaginationQuery } from "./__generated__/AllPostsPaginationQuery.graphql";

const fragment = graphql`
fragment AllPostsFragment on Query
@argumentDefinitions(
after: { type: "String" }
first: { type: "Int", defaultValue: 2 }
before: { type: "String" }
last: { type: "Int" }
)
@refetchable(queryName: "AllPostsPaginationQuery") {
pano {
allPosts(first: $first, after: $after, last: $last, before: $before)
@connection(key: "AllPostFragment_pano_allPosts") {
pageInfo {
startCursor
endCursor
}
edges {
cursor
node {
...PostItem_post
}
}
}
}
}
`;

interface Props {
allPosts: AllPostsFragment$key;
}

export function AllPosts(props: Props) {
const { data, refetch, hasNext, hasPrevious } = usePaginationFragment<
AllPostsPaginationQuery,
AllPostsFragment$key
>(fragment, props.allPosts);

const allPosts = data.pano.allPosts;

const loadPrevPage = useCallback(() => {
if (allPosts?.pageInfo.startCursor && hasPrevious) {
refetch({ before: allPosts.pageInfo.startCursor, last: 2 });
}
}, [allPosts?.pageInfo.startCursor, hasPrevious, refetch]);

const loadNextPage = useCallback(() => {
if (allPosts?.pageInfo.endCursor && hasNext) {
refetch({ after: allPosts.pageInfo.endCursor, first: 2 });
}
}, [allPosts?.pageInfo.endCursor, hasNext, refetch]);

return (
<section className="flex flex-col gap-4">
{data?.pano.allPosts?.edges?.map((edge) => {
if (!edge?.node) {
return null;
}

if (!edge.cursor) {
return null;
}

return <PostItem key={edge.cursor} post={edge.node} />;
})}

<div className="flex gap-2">
<Button variant="secondary" onClick={loadPrevPage} disabled={!hasPrevious}>
{"< Prev"}
</Button>
<Button variant="secondary" onClick={loadNextPage} disabled={!hasNext}>
{"Next >"}
</Button>
</div>
</section>
);
}
Loading

0 comments on commit d375fe4

Please sign in to comment.