Skip to content

Commit

Permalink
Merge pull request #18 from saroh-io/dashboard
Browse files Browse the repository at this point in the history
added concurrency
  • Loading branch information
himohitmehta committed Nov 29, 2023
2 parents b6e40c1 + 633e0b3 commit dc7d2b0
Show file tree
Hide file tree
Showing 7 changed files with 229 additions and 99 deletions.
31 changes: 31 additions & 0 deletions apps/application/app/api/sites/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { getSession } from "@/lib/auth";
import prisma from "@/lib/prisma";
import { NextResponse } from "next/server";
// import { NextResponse } from "next/server";

export async function GET(req, res) {
const session = await getSession();
if (!session) {
return NextResponse.json({
result: null,
status: "error",
message: "unauthorized",
});
}
// const {} = req.json();
const sites = await prisma.site.findMany({
where: {
user: {
id: session?.user.id,
},
},
orderBy: {
createdAt: "asc",
},
// ...(limit ? { take: limit } : {}),
});
return NextResponse.json({
result: sites,
status: "success",
});
}
9 changes: 9 additions & 0 deletions apps/application/app/app/(dashboard)/[siteId]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ReactNode } from "react";

export default function SiteLayout({ children }: { children: ReactNode }) {
return (
<div className="flex max-w-screen-xl flex-col space-y-12 p-8">
<div className="flex flex-col space-y-6">{children}</div>
</div>
);
}
54 changes: 54 additions & 0 deletions apps/application/app/app/(dashboard)/[siteId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import CreatePostButton from "@/components/create-post-button";
import Posts from "@/components/posts";
import { getSession } from "@/lib/auth";
import prisma from "@/lib/prisma";
import { notFound, redirect } from "next/navigation";
import React from "react";

export default async function SitePage({
params,
}: {
params: { siteId: string };
}) {
const session = await getSession();
if (!session) {
redirect("/login");
}
const data = await prisma.site.findUnique({
where: {
id: params.siteId,
},
});

if (!data || data.userId !== session.user.id) {
notFound();
}

const url = `${data.subdomain}.${process.env.NEXT_PUBLIC_ROOT_DOMAIN}`;

return (
<>
<div className="flex flex-col items-center justify-between space-y-4 sm:flex-row sm:space-y-0">
<div className="flex flex-col items-center space-y-2 sm:flex-row sm:space-x-4 sm:space-y-0">
<h1 className="w-60 truncate font-cal text-xl font-bold dark:text-white sm:w-auto sm:text-3xl">
All Posts for {data.name}
</h1>
<a
href={
process.env.NEXT_PUBLIC_VERCEL_ENV
? `https://${url}`
: `http://${data.subdomain}.localhost:3000`
}
target="_blank"
rel="noreferrer"
className="truncate rounded-md bg-stone-100 px-2 py-1 text-sm font-medium text-stone-600 transition-colors hover:bg-stone-200 dark:bg-stone-800 dark:text-stone-400 dark:hover:bg-stone-700"
>
{url}
</a>
</div>
<CreatePostButton />
</div>
<Posts siteId={params.siteId} />
</>
);
}
14 changes: 12 additions & 2 deletions apps/application/components/app/navbar/nav-tabs.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client";

import Link from "next/link";
import { useSelectedLayoutSegments } from "next/navigation";
import { useParams, useSelectedLayoutSegments } from "next/navigation";
import React from "react";

let tabs = [
Expand All @@ -24,10 +24,20 @@ let tabs = [

export default function NavTabs() {
const segments = useSelectedLayoutSegments();
const params = useParams();
const siteId = params.siteId;
const postTab = {
name: "Posts",
href: `/${siteId}`,
key: "posts",
};
const filteredTabs = tabs.filter((item) => item.key !== "sites");
const tabsWithPosts = siteId ? [...filteredTabs, postTab] : tabs;

console.log({ segments });
return (
<div className="-mb-0.5 flex h-12 items-center justify-start space-x-2 overflow-x-auto scrollbar-hide">
{tabs.map(({ name, href, key }) => (
{tabsWithPosts.map(({ name, href, key }) => (
<Link
key={href}
href={href}
Expand Down
216 changes: 121 additions & 95 deletions apps/application/components/app/navbar/store-switcher.tsx
Original file line number Diff line number Diff line change
@@ -1,110 +1,136 @@
"use client"
"use client";

import * as React from "react"
import { Check, ChevronsUpDown, PlusCircle, Store } from "lucide-react"
import * as React from "react";
import { Check, ChevronsUpDown, PlusCircle, Store } from "lucide-react";

import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
} from "@/components/ui/command"
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
} from "@/components/ui/command";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
// import { useStoreModal } from "@/hooks/use-store-modal"
import { useParams, useRouter } from "next/navigation"
import { useParams, useRouter } from "next/navigation";

type PopoverTriggerProps = React.ComponentPropsWithoutRef<typeof PopoverTrigger>
type PopoverTriggerProps = React.ComponentPropsWithoutRef<
typeof PopoverTrigger
>;

interface StoreSwitcherProps extends PopoverTriggerProps {
items: Record<string, any>[];
items: Record<string, any>[];
}

export default function StoreSwitcher({ className, items = [] }: StoreSwitcherProps) {
// const storeModal = useStoreModal();
const params = useParams();
const router = useRouter();
export default function StoreSwitcher({
className,
items = [],
}: StoreSwitcherProps) {
// const storeModal = useStoreModal();
const params = useParams();
const router = useRouter();
const [sites, setSites] = React.useState<
{
name: string;
id: string;
}[]
>([]);
const handleFetchSites = () => {
// fetch sites
fetch("/api/sites")
.then((res) => res.json())
.then((res) => {
console.log(res, "sites");
setSites(res.result);
})
.catch((err) => console.log(err));
};
React.useEffect(() => {
handleFetchSites();
}, []);

const formattedItems = items.map((item) => ({
label: item.name,
value: item.id
}));
const formattedItems = sites.map((item) => ({
label: item.name,
value: item.id,
}));

const currentStore = formattedItems.find((item) => item.value === params.storeId);
const currentStore = formattedItems.find(
(item) => item.value === params.siteId,
);

const [open, setOpen] = React.useState(false)
const [open, setOpen] = React.useState(false);

const onStoreSelect = (store: { value: string, label: string }) => {
setOpen(false);
router.push(`/${store.value}`);
};
const onStoreSelect = (store: { value: string; label: string }) => {
setOpen(false);
router.push(`/${store.value}`);
};

return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
variant="outline"
size="sm"
role="combobox"
aria-expanded={open}
aria-label="Select a store"
className={cn("w-[200px] justify-between", className)}
>
<Store className="mr-2 h-4 w-4" />
{currentStore?.label}
<ChevronsUpDown className="ml-auto h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[200px] p-0">
<Command>
<CommandList>
<CommandInput placeholder="Search store..." />
<CommandEmpty>No store found.</CommandEmpty>
<CommandGroup heading="Stores">
{formattedItems.map((store) => (
<CommandItem
key={store.value}
onSelect={() => onStoreSelect(store)}
className="text-sm"
>
<Store className="mr-2 h-4 w-4" />
{store.label}
<Check
className={cn(
"ml-auto h-4 w-4",
currentStore?.value === store.value
? "opacity-100"
: "opacity-0"
)}
/>
</CommandItem>
))}
</CommandGroup>
</CommandList>
<CommandSeparator />
<CommandList>
<CommandGroup>
<CommandItem
onSelect={() => {
setOpen(false)
// storeModal.onOpen()
}}
>
<PlusCircle className="mr-2 h-5 w-5" />
Create Store
</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
};
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
variant="outline"
size="sm"
role="combobox"
aria-expanded={open}
aria-label="Select a store"
className={cn("w-[200px] justify-between", className)}
>
<Store className="mr-2 h-4 w-4" />
{currentStore?.label}
<ChevronsUpDown className="ml-auto h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[200px] p-0">
<Command>
<CommandList>
<CommandInput placeholder="Search store..." />
<CommandEmpty>No store found.</CommandEmpty>
<CommandGroup heading="Stores">
{formattedItems.map((store) => (
<CommandItem
key={store.value}
onSelect={() => onStoreSelect(store)}
className="text-sm"
>
<Store className="mr-2 h-4 w-4" />
{store.label}
<Check
className={cn(
"ml-auto h-4 w-4",
currentStore?.value === store.value
? "opacity-100"
: "opacity-0",
)}
/>
</CommandItem>
))}
</CommandGroup>
</CommandList>
<CommandSeparator />
<CommandList>
<CommandGroup>
<CommandItem
onSelect={() => {
setOpen(false);
// storeModal.onOpen()
}}
>
<PlusCircle className="mr-2 h-5 w-5" />
Create Store
</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
}
2 changes: 1 addition & 1 deletion apps/application/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "**/*.js"],
"exclude": ["node_modules"]
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"db:migrate:deploy": "turbo run db:migrate:deploy",
"db:push": "turbo run db:push",
"db:seed": "turbo run db:seed",
"dev": "turbo run dev",
"dev": "turbo run dev --concurrency 100",
"lint": "turbo run lint",
"format": "prettier --write \"**/*.{ts,tsx,md}\""
},
Expand Down

5 comments on commit dc7d2b0

@vercel
Copy link

@vercel vercel bot commented on dc7d2b0 Nov 29, 2023

Choose a reason for hiding this comment

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

@vercel
Copy link

@vercel vercel bot commented on dc7d2b0 Nov 29, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

saroh-ui-site – ./apps/ui-site

saroh-ui-site-git-main-mishtusdotcom.vercel.app
saroh-ui-site.vercel.app
saroh-ui-site-mishtusdotcom.vercel.app
ui.saroh.io

@vercel
Copy link

@vercel vercel bot commented on dc7d2b0 Nov 29, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

app-saroh-io – ./apps/application

app-saroh-io.vercel.app
app-saroh-io-mishtusdotcom.vercel.app
app-saroh-io-git-main-mishtusdotcom.vercel.app
app.saroh.io

@vercel
Copy link

@vercel vercel bot commented on dc7d2b0 Nov 29, 2023

Choose a reason for hiding this comment

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

@vercel
Copy link

@vercel vercel bot commented on dc7d2b0 Nov 29, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

saroh-docs – ./apps/docs

saroh-docs-git-main-mishtusdotcom.vercel.app
saroh-docs-mishtusdotcom.vercel.app
saroh-docs.vercel.app
docs.saroh.io

Please sign in to comment.