diff --git a/.gitignore b/.gitignore index 0a8ae55..4550eff 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,6 @@ next-env.d.ts /.react-email/ .vscode -.contentlayer \ No newline at end of file +.contentlayer + +public/sw.js.map \ No newline at end of file diff --git a/app/(protected)/admin/system/domain-list.tsx b/app/(protected)/admin/system/domain-list.tsx index 110a383..d4db456 100644 --- a/app/(protected)/admin/system/domain-list.tsx +++ b/app/(protected)/admin/system/domain-list.tsx @@ -81,7 +81,7 @@ export default function DomainList({ user, action }: DomainListProps) { const [currentEditDomain, setCurrentEditDomain] = useState(null); const [currentPage, setCurrentPage] = useState(1); - const [pageSize, setPageSize] = useState(10); + const [pageSize, setPageSize] = useState(15); const [searchParams, setSearchParams] = useState({ slug: "", target: "", diff --git a/app/(protected)/admin/system/plan-list.tsx b/app/(protected)/admin/system/plan-list.tsx index 37b51f5..375bea6 100644 --- a/app/(protected)/admin/system/plan-list.tsx +++ b/app/(protected)/admin/system/plan-list.tsx @@ -73,7 +73,7 @@ export default function PlanList({ user, action }: PlanListProps) { const [currentEditPlan, setCurrentEditPlan] = useState(null); const [currentPage, setCurrentPage] = useState(1); - const [pageSize, setPageSize] = useState(10); + const [pageSize, setPageSize] = useState(15); const [searchParams, setSearchParams] = useState({ slug: "", target: "", diff --git a/app/(protected)/admin/urls/loading.tsx b/app/(protected)/admin/urls/loading.tsx index 6247767..66470b6 100644 --- a/app/(protected)/admin/urls/loading.tsx +++ b/app/(protected)/admin/urls/loading.tsx @@ -1,13 +1,8 @@ import { Skeleton } from "@/components/ui/skeleton"; -import { DashboardHeader } from "@/components/dashboard/header"; export default function DashboardUrlsLoading() { return ( <> -
diff --git a/app/(protected)/admin/urls/page.tsx b/app/(protected)/admin/urls/page.tsx index 5d28134..3a8a623 100644 --- a/app/(protected)/admin/urls/page.tsx +++ b/app/(protected)/admin/urls/page.tsx @@ -2,7 +2,6 @@ import { redirect } from "next/navigation"; import { getCurrentUser } from "@/lib/session"; import { constructMetadata } from "@/lib/utils"; -import { DashboardHeader } from "@/components/dashboard/header"; import UserUrlsList from "../../dashboard/urls/url-list"; @@ -18,12 +17,6 @@ export default async function DashboardPage() { return ( <> - (null); const [currentPage, setCurrentPage] = useState(1); - const [pageSize, setPageSize] = useState(10); + const [pageSize, setPageSize] = useState(15); const [searchParams, setSearchParams] = useState({ email: "", userName: "", diff --git a/app/(protected)/dashboard/records/record-list.tsx b/app/(protected)/dashboard/records/record-list.tsx index c7f8465..3027623 100644 --- a/app/(protected)/dashboard/records/record-list.tsx +++ b/app/(protected)/dashboard/records/record-list.tsx @@ -88,7 +88,7 @@ export default function UserRecordsList({ user, action }: RecordListProps) { const [currentEditRecord, setCurrentEditRecord] = useState(null); const [currentPage, setCurrentPage] = useState(1); - const [pageSize, setPageSize] = useState(10); + const [pageSize, setPageSize] = useState(15); const isAdmin = action.includes("/admin"); const t = useTranslations("List"); @@ -154,7 +154,7 @@ export default function UserRecordsList({ user, action }: RecordListProps) {
{t("Subdomain List")} - {t("Before using please read the")}{" "} + {t("Before using please read the")} {t("legitimacy review")} - . {t("See")}{" "} + . {t("See")} {t("examples")} - {" "} + {t("for more usage")}.
diff --git a/app/(protected)/dashboard/urls/export.tsx b/app/(protected)/dashboard/urls/export.tsx index 753f6cd..2711447 100644 --- a/app/(protected)/dashboard/urls/export.tsx +++ b/app/(protected)/dashboard/urls/export.tsx @@ -157,7 +157,10 @@ export const UrlExporter: React.FC<{ return ( - diff --git a/app/(protected)/dashboard/urls/loading.tsx b/app/(protected)/dashboard/urls/loading.tsx index 6247767..66470b6 100644 --- a/app/(protected)/dashboard/urls/loading.tsx +++ b/app/(protected)/dashboard/urls/loading.tsx @@ -1,13 +1,8 @@ import { Skeleton } from "@/components/ui/skeleton"; -import { DashboardHeader } from "@/components/dashboard/header"; export default function DashboardUrlsLoading() { return ( <> -
diff --git a/app/(protected)/dashboard/urls/page.tsx b/app/(protected)/dashboard/urls/page.tsx index b3f071e..0690e80 100644 --- a/app/(protected)/dashboard/urls/page.tsx +++ b/app/(protected)/dashboard/urls/page.tsx @@ -2,7 +2,6 @@ import { redirect } from "next/navigation"; import { getCurrentUser } from "@/lib/session"; import { constructMetadata } from "@/lib/utils"; -import { DashboardHeader } from "@/components/dashboard/header"; import UserUrlsList from "./url-list"; @@ -18,12 +17,6 @@ export default async function DashboardPage() { return ( <> - (null); @@ -197,80 +204,101 @@ export default function UserUrlsList({ user, action }: UrlListProps) { ); - const rendeSeachInputs = () => ( -
-
- { - setSearchParams({ - ...searchParams, - slug: e.target.value, - }); - }} - /> - {searchParams.slug && ( - - )} -
+ const renderSearchInputs = () => { + const [searchType, setSearchType] = useState< + "slug" | "target" | "userName" + >("slug"); -
- { - setSearchParams({ - ...searchParams, - target: e.target.value, - }); - }} - /> - {searchParams.target && ( - - )} -
+ const getCurrentSearchValue = () => { + switch (searchType) { + case "slug": + return searchParams.slug; + case "target": + return searchParams.target; + case "userName": + return searchParams.userName; + default: + return ""; + } + }; - {user.role === "ADMIN" && ( -
+ const handleSearchChange = (value: string) => { + setSearchParams({ + ...searchParams, + slug: searchType === "slug" ? value : "", + target: searchType === "target" ? value : "", + userName: searchType === "userName" ? value : "", + }); + }; + + const handleClearSearch = () => { + handleSearchChange(""); + }; + + const getPlaceholder = () => { + switch (searchType) { + case "slug": + return t("Search by slug") + "..."; + case "target": + return t("Search by target") + "..."; + case "userName": + return t("Search by username") + "..."; + default: + return t("Search") + "..."; + } + }; + + const searchOptions = [ + { value: "slug", label: t("Link Slug") }, + { value: "target", label: t("Link Target") }, + ...(user.role === "ADMIN" + ? [{ value: "userName", label: t("Username") }] + : []), + ]; + + const currentSearchValue = getCurrentSearchValue(); + + return ( +
+ +
{ - setSearchParams({ - ...searchParams, - userName: e.target.value, - }); - }} + className="h-10 rounded-l-none border-l-0 pr-8 text-sm" + placeholder={getPlaceholder()} + value={currentSearchValue} + onChange={(e) => handleSearchChange(e.target.value)} /> - {searchParams.userName && ( + {currentSearchValue && ( )}
- )} -
- ); +
+ ); + }; const rendeClicks = (short: ShortUrlFormData) => ( <> @@ -650,13 +678,16 @@ export default function UserUrlsList({ user, action }: UrlListProps) { return ( <> {/* Tabs */} -
+
{pathname === "/dashboard" && ( -

{t("Short URLs")}

+

{t("Short URLs")}

)} setCurrentView("List")} value="List"> @@ -678,8 +709,8 @@ export default function UserUrlsList({ user, action }: UrlListProps) { )} - {/*

Total: {data?.total || 0}

*/} -
+
+ {renderSearchInputs()}
- - {pathname !== "/dashboard" && } - {rendeSeachInputs()} + {pathname !== "/dashboard" && } + + {rendeList()} - - {pathname !== "/dashboard" && } - {rendeSeachInputs()} + {rendeGrid()} {selectedUrl?.id && ( diff --git a/app/emails/sent/page.tsx b/app/emails/sent/page.tsx index b09ee86..7d9ad16 100644 --- a/app/emails/sent/page.tsx +++ b/app/emails/sent/page.tsx @@ -14,5 +14,5 @@ export default async function SentEmailPage() { if (!user?.id) redirect("/login"); - return ; + return ; } diff --git a/components/email/EmailList.tsx b/components/email/EmailList.tsx index 1d7363b..f05a9db 100644 --- a/components/email/EmailList.tsx +++ b/components/email/EmailList.tsx @@ -54,7 +54,7 @@ export default function EmailList({ const [isRefreshing, setIsRefreshing] = useState(false); const [isAutoRefresh, setIsAutoRefresh] = useState(false); const [currentPage, setCurrentPage] = useState(1); - const [pageSize, setPageSize] = useState(10); + const [pageSize, setPageSize] = useState(15); const [selectedEmails, setSelectedEmails] = useState([]); const [showMutiCheckBox, setShowMutiCheckBox] = useState(false); diff --git a/components/email/EmailSidebar.tsx b/components/email/EmailSidebar.tsx index 9043821..072acaf 100644 --- a/components/email/EmailSidebar.tsx +++ b/components/email/EmailSidebar.tsx @@ -1,6 +1,6 @@ "use client"; -import { useEffect, useMemo, useState, useTransition } from "react"; +import { useEffect, useState, useTransition } from "react"; import { User, UserEmail } from "@prisma/client"; import randomName from "@scaleway/random-name"; import { @@ -45,7 +45,6 @@ import { TooltipTrigger, } from "../ui/tooltip"; import { SendEmailModal } from "./SendEmailModal"; -import SendsEmailList from "./SendsEmailList"; interface EmailSidebarProps { user: User; @@ -83,7 +82,7 @@ export default function EmailSidebar({ const [currentPage, setCurrentPage] = useState(1); const [onlyUnread, setOnlyUnread] = useState(false); - const [pageSize, setPageSize] = useState(10); + const [pageSize, setPageSize] = useState(15); const { data, isLoading, error, mutate } = useSWR<{ list: UserEmailList[]; @@ -338,6 +337,7 @@ export default function EmailSidebar({ "bg-neutral-200 dark:bg-neutral-800 dark:hover:bg-gray-700": onlyUnread, }, + { "col-span-2": user.role !== "ADMIN" }, )} onClick={() => { setOnlyUnread(!onlyUnread); @@ -363,28 +363,30 @@ export default function EmailSidebar({
{/* Admin Mode */} -
setAdminModel(!isAdminModel)} - className={cn( - "flex cursor-pointer flex-col items-center gap-1 rounded-md bg-neutral-100 px-1 pb-1 pt-2 transition-colors hover:bg-neutral-200 dark:bg-neutral-800 dark:hover:bg-gray-700", - { - "bg-neutral-200 dark:bg-neutral-800 dark:hover:bg-gray-700": - isAdminModel, - }, - )} - > -
- -

- {t("Admin Mode")} -

+ {user.role === "ADMIN" && ( +
setAdminModel(!isAdminModel)} + className={cn( + "flex cursor-pointer flex-col items-center gap-1 rounded-md bg-neutral-100 px-1 pb-1 pt-2 transition-colors hover:bg-neutral-200 dark:bg-neutral-800 dark:hover:bg-gray-700", + { + "bg-neutral-200 dark:bg-neutral-800 dark:hover:bg-gray-700": + isAdminModel, + }, + )} + > +
+ +

+ {t("Admin Mode")} +

+
+ setAdminModel(v)} + />
- setAdminModel(v)} - /> -
+ )}
)}
diff --git a/components/email/SendsEmailList.tsx b/components/email/SendsEmailList.tsx index c00ae4c..a8c4fce 100644 --- a/components/email/SendsEmailList.tsx +++ b/components/email/SendsEmailList.tsx @@ -1,12 +1,11 @@ "use client"; import { useCallback, useState } from "react"; -import { UserSendEmail } from "@prisma/client"; +import { User, UserSendEmail } from "@prisma/client"; import { useTranslations } from "next-intl"; import useSWR from "swr"; import { cn, fetcher, formatDate, htmlToText, nFormatter } from "@/lib/utils"; -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Skeleton } from "@/components/ui/skeleton"; @@ -19,9 +18,9 @@ import { } from "../ui/collapsible"; import { Switch } from "../ui/switch"; -export default function SendsEmailList({}: {}) { +export default function SendsEmailList({ user }: { user: User }) { const [currentPage, setCurrentPage] = useState(1); - const [pageSize, setPageSize] = useState(10); + const [pageSize, setPageSize] = useState(15); const [isAdminModel, setAdminModel] = useState(false); const [searchQuery, setSearchQuery] = useState(""); @@ -72,28 +71,30 @@ export default function SendsEmailList({}: {}) {
{/* Admin Mode */} -
setAdminModel(!isAdminModel)} - className={cn( - "flex cursor-pointer flex-col items-center gap-1 rounded-md bg-neutral-100 px-1 pb-1 pt-2 transition-colors hover:bg-neutral-200 dark:bg-neutral-800 dark:hover:bg-gray-700", - { - "bg-neutral-200 dark:bg-neutral-800 dark:hover:bg-gray-700": - isAdminModel, - }, - )} - > -
- -

- {t("Admin Mode")} -

+ {user.role === "ADMIN" && ( +
setAdminModel(!isAdminModel)} + className={cn( + "flex cursor-pointer flex-col items-center gap-1 rounded-md bg-neutral-100 px-1 pb-1 pt-2 transition-colors hover:bg-neutral-200 dark:bg-neutral-800 dark:hover:bg-gray-700", + { + "bg-neutral-200 dark:bg-neutral-800 dark:hover:bg-gray-700": + isAdminModel, + }, + )} + > +
+ +

+ {t("Admin Mode")} +

+
+ setAdminModel(v)} + />
- setAdminModel(v)} - /> -
+ )}
{ if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"sw.js","sources":["../../../../../private/var/folders/9b/3qmyp8zd2xvdspdrp149fyg00000gn/T/977104d8cfe0780c86c877e86d1bb149/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/songjunxi/Desktop/repos/wr.do/node_modules/.pnpm/workbox-routing@6.6.0/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/songjunxi/Desktop/repos/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from '/Users/songjunxi/Desktop/repos/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/songjunxi/Desktop/repos/wr.do/node_modules/.pnpm/workbox-core@6.6.0/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"} \ No newline at end of file