From 8eba47ca4a3aeb0b8052c20593998049f5eb770e Mon Sep 17 00:00:00 2001 From: DevMirza Date: Tue, 30 Jan 2024 09:21:04 +0000 Subject: [PATCH 1/9] Unblock Page From 3b89f92843b830be1058cfeb6d22bc09b97a06f2 Mon Sep 17 00:00:00 2001 From: DevMirza Date: Tue, 30 Jan 2024 09:29:23 +0000 Subject: [PATCH 2/9] add Table component --- components/ui/table.tsx | 117 ++++++++++++++++++++++++++++++++++++++++ package-lock.json | 32 +++++++++++ package.json | 1 + 3 files changed, 150 insertions(+) create mode 100644 components/ui/table.tsx diff --git a/components/ui/table.tsx b/components/ui/table.tsx new file mode 100644 index 0000000..7f3502f --- /dev/null +++ b/components/ui/table.tsx @@ -0,0 +1,117 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Table = React.forwardRef< + HTMLTableElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+ + +)) +Table.displayName = "Table" + +const TableHeader = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableHeader.displayName = "TableHeader" + +const TableBody = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableBody.displayName = "TableBody" + +const TableFooter = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + tr]:last:border-b-0", + className + )} + {...props} + /> +)) +TableFooter.displayName = "TableFooter" + +const TableRow = React.forwardRef< + HTMLTableRowElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableRow.displayName = "TableRow" + +const TableHead = React.forwardRef< + HTMLTableCellElement, + React.ThHTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TableHead.displayName = "TableHead" + +const TableCell = React.forwardRef< + HTMLTableCellElement, + React.TdHTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableCell.displayName = "TableCell" + +const TableCaption = React.forwardRef< + HTMLTableCaptionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TableCaption.displayName = "TableCaption" + +export { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, + TableCaption, +} diff --git a/package-lock.json b/package-lock.json index 78f5a99..4a230f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", + "@tanstack/react-table": "^8.11.7", "@uploadthing/react": "^6.2.2", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", @@ -1639,6 +1640,37 @@ "tslib": "^2.4.0" } }, + "node_modules/@tanstack/react-table": { + "version": "8.11.7", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.11.7.tgz", + "integrity": "sha512-ZbzfMkLjxUTzNPBXJYH38pv2VpC9WUA+Qe5USSHEBz0dysDTv4z/ARI3csOed/5gmlmrPzVUN3UXGuUMbod3Jg==", + "dependencies": { + "@tanstack/table-core": "8.11.7" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.11.7", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.11.7.tgz", + "integrity": "sha512-N3ksnkbPbsF3PjubuZCB/etTqvctpXWRHIXTmYfJFnhynQKjeZu8BCuHvdlLPpumKbA+bjY4Ay9AELYLOXPWBg==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", diff --git a/package.json b/package.json index d216917..a8b1ac7 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", + "@tanstack/react-table": "^8.11.7", "@uploadthing/react": "^6.2.2", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", From e4a030ee9cedee68bce63407d1d08d91e54c4687 Mon Sep 17 00:00:00 2001 From: DevMirza Date: Tue, 30 Jan 2024 09:36:24 +0000 Subject: [PATCH 3/9] demo table --- .../community/_components/column.ts | 27 +++++++ .../community/_components/data-table.tsx | 80 +++++++++++++++++++ .../u/[username]/community/page.tsx | 20 ++++- 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 app/(dashboard)/u/[username]/community/_components/column.ts create mode 100644 app/(dashboard)/u/[username]/community/_components/data-table.tsx diff --git a/app/(dashboard)/u/[username]/community/_components/column.ts b/app/(dashboard)/u/[username]/community/_components/column.ts new file mode 100644 index 0000000..4c566f6 --- /dev/null +++ b/app/(dashboard)/u/[username]/community/_components/column.ts @@ -0,0 +1,27 @@ +"use client"; + +import { ColumnDef } from "@tanstack/react-table"; + +// This type is used to define the shape of our data. +// You can use a Zod schema here if you want. +export type Payment = { + id: string; + amount: number; + status: "pending" | "processing" | "success" | "failed"; + email: string; +}; + +export const columns: ColumnDef[] = [ + { + accessorKey: "status", + header: "Status", + }, + { + accessorKey: "email", + header: "Email", + }, + { + accessorKey: "amount", + header: "Amount", + }, +]; diff --git a/app/(dashboard)/u/[username]/community/_components/data-table.tsx b/app/(dashboard)/u/[username]/community/_components/data-table.tsx new file mode 100644 index 0000000..ba814ac --- /dev/null +++ b/app/(dashboard)/u/[username]/community/_components/data-table.tsx @@ -0,0 +1,80 @@ +"use client"; + +import { + ColumnDef, + flexRender, + getCoreRowModel, + useReactTable, +} from "@tanstack/react-table"; + +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; + +interface DataTableProps { + columns: ColumnDef[]; + data: TData[]; +} + +export function DataTable({ + columns, + data, +}: DataTableProps) { + const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + }); + + return ( +
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext() + )} + + ); + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + )) + ) : ( + + + No results. + + + )} + +
+
+ ); +} diff --git a/app/(dashboard)/u/[username]/community/page.tsx b/app/(dashboard)/u/[username]/community/page.tsx index f3dbc5c..eed2c8a 100644 --- a/app/(dashboard)/u/[username]/community/page.tsx +++ b/app/(dashboard)/u/[username]/community/page.tsx @@ -1,10 +1,28 @@ import React from "react"; +import { DataTable } from "./_components/data-table"; +import { Payment, columns } from "./_components/column"; + +async function getData(): Promise { + // Fetch data from your API here. + return [ + { + id: "728ed52f", + amount: 100, + status: "pending", + email: "m@example.com", + }, + // ... + ]; +} + +const Community = async () => { + const data = await getData(); -const Community = () => { return (

Community Settings

+
); From bf7af71d3d0f051aaea97c739f7ae63007222a62 Mon Sep 17 00:00:00 2001 From: DevMirza Date: Tue, 30 Jan 2024 09:39:56 +0000 Subject: [PATCH 4/9] update --- app/(dashboard)/u/[username]/community/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/(dashboard)/u/[username]/community/page.tsx b/app/(dashboard)/u/[username]/community/page.tsx index eed2c8a..aeeb2b2 100644 --- a/app/(dashboard)/u/[username]/community/page.tsx +++ b/app/(dashboard)/u/[username]/community/page.tsx @@ -22,8 +22,8 @@ const Community = async () => {

Community Settings

-
+
); }; From 5a1bbcfa3330061a50c040d667b2fdf960d269ca Mon Sep 17 00:00:00 2001 From: DevMirza Date: Tue, 30 Jan 2024 09:48:00 +0000 Subject: [PATCH 5/9] update to show data from db --- .../u/[username]/community/page.tsx | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/app/(dashboard)/u/[username]/community/page.tsx b/app/(dashboard)/u/[username]/community/page.tsx index aeeb2b2..70fcece 100644 --- a/app/(dashboard)/u/[username]/community/page.tsx +++ b/app/(dashboard)/u/[username]/community/page.tsx @@ -1,29 +1,25 @@ -import React from "react"; +import { getBlockedUsers } from "@/lib/block-service"; +import { columns } from "./_components/column"; import { DataTable } from "./_components/data-table"; -import { Payment, columns } from "./_components/column"; - -async function getData(): Promise { - // Fetch data from your API here. - return [ - { - id: "728ed52f", - amount: 100, - status: "pending", - email: "m@example.com", - }, - // ... - ]; -} +import { format } from "date-fns"; const Community = async () => { - const data = await getData(); + const blockedUsers = await getBlockedUsers(); + + const formattedData = blockedUsers.map((block) => ({ + ...block, + userId: block.blocked.id, + imageUrl: block.blocked.imageUrl, + username: block.blocked.username, + createdAt: format(new Date(block.blocked.createdAt), "dd/MM/yyyy"), + })); return (

Community Settings

- +
); }; From e90b84a2aca8053de767870517c39e358b067bb5 Mon Sep 17 00:00:00 2001 From: DevMirza Date: Thu, 1 Feb 2024 11:48:21 +0000 Subject: [PATCH 6/9] update --- .../community/_components/column.ts | 27 ------------------- .../community/_components/column.tsx | 22 +++++++++++++++ 2 files changed, 22 insertions(+), 27 deletions(-) delete mode 100644 app/(dashboard)/u/[username]/community/_components/column.ts create mode 100644 app/(dashboard)/u/[username]/community/_components/column.tsx diff --git a/app/(dashboard)/u/[username]/community/_components/column.ts b/app/(dashboard)/u/[username]/community/_components/column.ts deleted file mode 100644 index 4c566f6..0000000 --- a/app/(dashboard)/u/[username]/community/_components/column.ts +++ /dev/null @@ -1,27 +0,0 @@ -"use client"; - -import { ColumnDef } from "@tanstack/react-table"; - -// This type is used to define the shape of our data. -// You can use a Zod schema here if you want. -export type Payment = { - id: string; - amount: number; - status: "pending" | "processing" | "success" | "failed"; - email: string; -}; - -export const columns: ColumnDef[] = [ - { - accessorKey: "status", - header: "Status", - }, - { - accessorKey: "email", - header: "Email", - }, - { - accessorKey: "amount", - header: "Amount", - }, -]; diff --git a/app/(dashboard)/u/[username]/community/_components/column.tsx b/app/(dashboard)/u/[username]/community/_components/column.tsx new file mode 100644 index 0000000..60e68e3 --- /dev/null +++ b/app/(dashboard)/u/[username]/community/_components/column.tsx @@ -0,0 +1,22 @@ +"use client"; + +import { ColumnDef } from "@tanstack/react-table"; + +export type BlockedUser = { + id: string; + userId: string; + imageUrl: string; + username: string; + createdAt: string; +}; + +export const columns: ColumnDef[] = [ + { + accessorKey: "username", + header: "username", + }, + { + accessorKey: "createdAt", + header: "Created At", + }, +]; From 1581c5bae3d4edaf95b177409e0423ea30fd2796 Mon Sep 17 00:00:00 2001 From: DevMirza Date: Fri, 2 Feb 2024 14:02:59 +0000 Subject: [PATCH 7/9] trunk --- .trunk/.gitignore | 9 ++++++++ .trunk/configs/.markdownlint.yaml | 10 +++++++++ .trunk/configs/.yamllint.yaml | 10 +++++++++ .trunk/configs/svgo.config.js | 14 ++++++++++++ .trunk/trunk.yaml | 37 +++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+) create mode 100644 .trunk/.gitignore create mode 100644 .trunk/configs/.markdownlint.yaml create mode 100644 .trunk/configs/.yamllint.yaml create mode 100644 .trunk/configs/svgo.config.js create mode 100644 .trunk/trunk.yaml diff --git a/.trunk/.gitignore b/.trunk/.gitignore new file mode 100644 index 0000000..15966d0 --- /dev/null +++ b/.trunk/.gitignore @@ -0,0 +1,9 @@ +*out +*logs +*actions +*notifications +*tools +plugins +user_trunk.yaml +user.yaml +tmp diff --git a/.trunk/configs/.markdownlint.yaml b/.trunk/configs/.markdownlint.yaml new file mode 100644 index 0000000..fb94039 --- /dev/null +++ b/.trunk/configs/.markdownlint.yaml @@ -0,0 +1,10 @@ +# Autoformatter friendly markdownlint config (all formatting rules disabled) +default: true +blank_lines: false +bullet: false +html: false +indentation: false +line_length: false +spaces: false +url: false +whitespace: false diff --git a/.trunk/configs/.yamllint.yaml b/.trunk/configs/.yamllint.yaml new file mode 100644 index 0000000..4d44466 --- /dev/null +++ b/.trunk/configs/.yamllint.yaml @@ -0,0 +1,10 @@ +rules: + quoted-strings: + required: only-when-needed + extra-allowed: ["{|}"] + empty-values: + forbid-in-block-mappings: true + forbid-in-flow-mappings: true + key-duplicates: {} + octal-values: + forbid-implicit-octal: true diff --git a/.trunk/configs/svgo.config.js b/.trunk/configs/svgo.config.js new file mode 100644 index 0000000..b257d13 --- /dev/null +++ b/.trunk/configs/svgo.config.js @@ -0,0 +1,14 @@ +module.exports = { + plugins: [ + { + name: "preset-default", + params: { + overrides: { + removeViewBox: false, // https://github.com/svg/svgo/issues/1128 + sortAttrs: true, + removeOffCanvasPaths: true, + }, + }, + }, + ], +}; diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml new file mode 100644 index 0000000..592bbe5 --- /dev/null +++ b/.trunk/trunk.yaml @@ -0,0 +1,37 @@ +# This file controls the behavior of Trunk: https://docs.trunk.io/cli +# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml +version: 0.1 +cli: + version: 1.19.0 +# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins) +plugins: + sources: + - id: trunk + ref: v1.4.2 + uri: https://github.com/trunk-io/plugins +# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes) +runtimes: + enabled: + - node@18.12.1 + - python@3.10.8 +# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration) +lint: + enabled: + - actionlint@1.6.26 + - checkov@3.2.5 + - eslint@8.56.0 + - git-diff-check + - markdownlint@0.39.0 + - osv-scanner@1.6.2 + - prettier@3.2.4 + - svgo@3.2.0 + - trivy@0.49.0 + - trufflehog@3.66.3 + - yamllint@1.33.0 +actions: + disabled: + - trunk-announce + - trunk-check-pre-push + - trunk-fmt-pre-commit + enabled: + - trunk-upgrade-available From 9d5ec7b6d6ee069c485f5e5e3f099cd7f2640605 Mon Sep 17 00:00:00 2001 From: DevMirza Date: Tue, 27 Feb 2024 09:58:42 +0000 Subject: [PATCH 8/9] update coloumn --- .../community/_components/column.tsx | 37 ++++++++++++++++++- .../community/_components/unblock-button.tsx | 5 +++ 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 app/(dashboard)/u/[username]/community/_components/unblock-button.tsx diff --git a/app/(dashboard)/u/[username]/community/_components/column.tsx b/app/(dashboard)/u/[username]/community/_components/column.tsx index 60e68e3..736198c 100644 --- a/app/(dashboard)/u/[username]/community/_components/column.tsx +++ b/app/(dashboard)/u/[username]/community/_components/column.tsx @@ -1,6 +1,10 @@ "use client"; +import { Button } from "@/components/ui/button"; +import { UserAvatar } from "@/components/user-avatar"; import { ColumnDef } from "@tanstack/react-table"; +import { ArrowUpDown } from "lucide-react"; +import { UnblockButton } from "./unblock-button"; export type BlockedUser = { id: string; @@ -13,10 +17,39 @@ export type BlockedUser = { export const columns: ColumnDef[] = [ { accessorKey: "username", - header: "username", + header: ({ column }) => ( + + ), + cell: ({ row }) => ( +
+ + {row.original.username} +
+ ), }, { accessorKey: "createdAt", - header: "Created At", + header: ({ column }) => ( + + ), + }, + { + id: "actions", + cell: ({ row }) => , }, ]; diff --git a/app/(dashboard)/u/[username]/community/_components/unblock-button.tsx b/app/(dashboard)/u/[username]/community/_components/unblock-button.tsx new file mode 100644 index 0000000..c9648c4 --- /dev/null +++ b/app/(dashboard)/u/[username]/community/_components/unblock-button.tsx @@ -0,0 +1,5 @@ +import React from "react"; + +export const UnblockButton = () => { + return
UnblockButton
; +}; From c11b7269f483befb4ba2ca39fa2e6f762cee614c Mon Sep 17 00:00:00 2001 From: DevMirza Date: Tue, 27 Feb 2024 10:05:07 +0000 Subject: [PATCH 9/9] update unblockbutton --- .../community/_components/unblock-button.tsx | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/app/(dashboard)/u/[username]/community/_components/unblock-button.tsx b/app/(dashboard)/u/[username]/community/_components/unblock-button.tsx index c9648c4..8d14c31 100644 --- a/app/(dashboard)/u/[username]/community/_components/unblock-button.tsx +++ b/app/(dashboard)/u/[username]/community/_components/unblock-button.tsx @@ -1,5 +1,33 @@ -import React from "react"; +import { onUnblock } from "@/actions/block"; +import { Button } from "@/components/ui/button"; +import { useTransition } from "react"; +import { toast } from "sonner"; -export const UnblockButton = () => { - return
UnblockButton
; +interface UnblockButtonProps { + userId: string; +} + +export const UnblockButton = ({ userId }: UnblockButtonProps) => { + const [isPending, startTransition] = useTransition(); + + const onClick = () => { + startTransition(() => { + onUnblock(userId) + .then((result) => + toast.success(`User ${result.blocked.username} unblocked`) + ) + .catch(() => toast.error("Something went wrong")); + }); + }; + return ( + + ); };