mirror of
https://github.com/fergalmoran/mixyboos.git
synced 2025-12-22 09:41:39 +00:00
Initial user profile page added
This commit is contained in:
@@ -1,49 +0,0 @@
|
||||
import React from "react";
|
||||
import getData from './data'
|
||||
import MainPlayer from "@/components/widgets/audio/large-audio-player";
|
||||
import {getSession} from "next-auth/react";
|
||||
|
||||
interface MixesPageProps {
|
||||
params: {
|
||||
userName: string;
|
||||
};
|
||||
}
|
||||
|
||||
const MixesPage: React.FC<MixesPageProps> = async ({
|
||||
params,
|
||||
}: MixesPageProps) => {
|
||||
const {user, mixes} = await getData(params.userName)
|
||||
return (<div>
|
||||
<div className="flex items-center justify-between space-y-2"><h2
|
||||
className="text-3xl font-bold tracking-tight">Mixes for {user.name || user.username}</h2>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="grid gap-2">
|
||||
<button
|
||||
className="inline-flex items-center rounded-md text-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2 w-[260px] justify-start text-left font-normal"
|
||||
id="date" type="button" aria-haspopup="dialog" aria-expanded="false" aria-controls="radix-:r7:"
|
||||
data-state="closed">
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"
|
||||
className="mr-2 h-4 w-4">
|
||||
<path
|
||||
d="M4.5 1C4.77614 1 5 1.22386 5 1.5V2H10V1.5C10 1.22386 10.2239 1 10.5 1C10.7761 1 11 1.22386 11 1.5V2H12.5C13.3284 2 14 2.67157 14 3.5V12.5C14 13.3284 13.3284 14 12.5 14H2.5C1.67157 14 1 13.3284 1 12.5V3.5C1 2.67157 1.67157 2 2.5 2H4V1.5C4 1.22386 4.22386 1 4.5 1ZM10 3V3.5C10 3.77614 10.2239 4 10.5 4C10.7761 4 11 3.77614 11 3.5V3H12.5C12.7761 3 13 3.22386 13 3.5V5H2V3.5C2 3.22386 2.22386 3 2.5 3H4V3.5C4 3.77614 4.22386 4 4.5 4C4.77614 4 5 3.77614 5 3.5V3H10ZM2 6V12.5C2 12.7761 2.22386 13 2.5 13H12.5C12.7761 13 13 12.7761 13 12.5V6H2ZM7 7.5C7 7.22386 7.22386 7 7.5 7C7.77614 7 8 7.22386 8 7.5C8 7.77614 7.77614 8 7.5 8C7.22386 8 7 7.77614 7 7.5ZM9.5 7C9.22386 7 9 7.22386 9 7.5C9 7.77614 9.22386 8 9.5 8C9.77614 8 10 7.77614 10 7.5C10 7.22386 9.77614 7 9.5 7ZM11 7.5C11 7.22386 11.2239 7 11.5 7C11.7761 7 12 7.22386 12 7.5C12 7.77614 11.7761 8 11.5 8C11.2239 8 11 7.77614 11 7.5ZM11.5 9C11.2239 9 11 9.22386 11 9.5C11 9.77614 11.2239 10 11.5 10C11.7761 10 12 9.77614 12 9.5C12 9.22386 11.7761 9 11.5 9ZM9 9.5C9 9.22386 9.22386 9 9.5 9C9.77614 9 10 9.22386 10 9.5C10 9.77614 9.77614 10 9.5 10C9.22386 10 9 9.77614 9 9.5ZM7.5 9C7.22386 9 7 9.22386 7 9.5C7 9.77614 7.22386 10 7.5 10C7.77614 10 8 9.77614 8 9.5C8 9.22386 7.77614 9 7.5 9ZM5 9.5C5 9.22386 5.22386 9 5.5 9C5.77614 9 6 9.22386 6 9.5C6 9.77614 5.77614 10 5.5 10C5.22386 10 5 9.77614 5 9.5ZM3.5 9C3.22386 9 3 9.22386 3 9.5C3 9.77614 3.22386 10 3.5 10C3.77614 10 4 9.77614 4 9.5C4 9.22386 3.77614 9 3.5 9ZM3 11.5C3 11.2239 3.22386 11 3.5 11C3.77614 11 4 11.2239 4 11.5C4 11.7761 3.77614 12 3.5 12C3.22386 12 3 11.7761 3 11.5ZM5.5 11C5.22386 11 5 11.2239 5 11.5C5 11.7761 5.22386 12 5.5 12C5.77614 12 6 11.7761 6 11.5C6 11.2239 5.77614 11 5.5 11ZM7 11.5C7 11.2239 7.22386 11 7.5 11C7.77614 11 8 11.2239 8 11.5C8 11.7761 7.77614 12 7.5 12C7.22386 12 7 11.7761 7 11.5ZM9.5 11C9.22386 11 9 11.2239 9 11.5C9 11.7761 9.22386 12 9.5 12C9.77614 12 10 11.7761 10 11.5C10 11.2239 9.77614 11 9.5 11Z"
|
||||
fill="currentColor" fill-rule="evenodd" clipRule="evenodd"></path>
|
||||
</svg>
|
||||
Jan 20, 2023 - Feb 09, 2023
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
className="inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground shadow hover:bg-primary/90 h-9 px-4 py-2">Download
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
{mixes.map(mix => (<div key={mix.id}>
|
||||
<div className="border-b-2">
|
||||
<MainPlayer mix={mix}/>
|
||||
</div>
|
||||
</div>))}
|
||||
</div>
|
||||
</div>);
|
||||
};
|
||||
|
||||
export default MixesPage;
|
||||
@@ -6,10 +6,10 @@ import { api } from "@/lib/utils/api";
|
||||
export default function Page({
|
||||
params,
|
||||
}: {
|
||||
params: { userName: string; mixSlug: string };
|
||||
params: { username: string; mixSlug: string };
|
||||
}) {
|
||||
const mixQuery = api.mix.getByUserAndSlug.useQuery({
|
||||
userName: params.userName,
|
||||
username: params.username,
|
||||
mixSlug: params.mixSlug,
|
||||
});
|
||||
const mix = mixQuery?.data;
|
||||
15
src/app/[username]/data.ts
Normal file
15
src/app/[username]/data.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { db } from "@/server/db";
|
||||
import raise from "@/lib/utils/errors";
|
||||
|
||||
async function getData(username: string) {
|
||||
const user = await db.query.users.findFirst({
|
||||
where: (users, { eq }) => eq(users.username, username),
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return raise("User not found");
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
export default getData;
|
||||
19
src/app/[username]/layout.tsx
Normal file
19
src/app/[username]/layout.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import getData from "./data";
|
||||
|
||||
const UserPageLayout = async ({
|
||||
children,
|
||||
params,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
params: { username: string };
|
||||
}) => {
|
||||
console.log("layout", "username", params);
|
||||
const user = await getData(params.username);
|
||||
return (
|
||||
<>
|
||||
<section className="h-500-px relative block">{user.username}</section>
|
||||
<div>{children}</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default UserPageLayout;
|
||||
@@ -2,10 +2,10 @@ import {db} from "@/server/db";
|
||||
import raise from "@/lib/utils/errors";
|
||||
import {mapMixToMixModel} from "@/lib/utils/mappers/mixMapper";
|
||||
|
||||
async function getData(userName: string) {
|
||||
async function getData(username: string) {
|
||||
|
||||
const user = await db.query.users.findFirst({
|
||||
where: (users, {eq}) => eq(users.username, userName)
|
||||
where: (users, {eq}) => eq(users.username, username)
|
||||
})
|
||||
|
||||
if (!user) {
|
||||
41
src/app/[username]/mixes/page.tsx
Normal file
41
src/app/[username]/mixes/page.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import React from "react";
|
||||
import getData from './data'
|
||||
import MainPlayer from "@/components/widgets/audio/large-audio-player";
|
||||
import {Icons} from "@/components/icons";
|
||||
import {Button} from "@/components/ui/button";
|
||||
|
||||
interface MixesPageProps {
|
||||
params: {
|
||||
username: string;
|
||||
};
|
||||
}
|
||||
|
||||
const MixesPage: React.FC<MixesPageProps> = async ({
|
||||
params,
|
||||
}: MixesPageProps) => {
|
||||
const {user, mixes} = await getData(params.username)
|
||||
return (<div>
|
||||
<div className="flex items-center justify-between space-y-2"><h2
|
||||
className="text-3xl font-bold tracking-tight">Mixes for {user.name || user.username}</h2>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="grid gap-2">
|
||||
<Button>
|
||||
<Icons.share className="mr-2 h-4 w-4"/> Share
|
||||
</Button>
|
||||
</div>
|
||||
<Button>
|
||||
<Icons.play className="mr-2 h-4 w-4"/> Play all
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
{mixes.map(mix => (<div key={mix.id}>
|
||||
<div className="border-b-2">
|
||||
<MainPlayer mix={mix}/>
|
||||
</div>
|
||||
</div>))}
|
||||
</div>
|
||||
</div>);
|
||||
};
|
||||
|
||||
export default MixesPage;
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PauseCircleIcon, PlayCircleIcon } from "lucide-react";
|
||||
import {
|
||||
Activity,
|
||||
AlertCircle,
|
||||
@@ -29,10 +28,13 @@ import {
|
||||
Moon,
|
||||
MoreVertical,
|
||||
Pizza,
|
||||
PauseCircleIcon,
|
||||
PlayCircleIcon,
|
||||
Plus,
|
||||
RadioTower,
|
||||
Rocket,
|
||||
Save,
|
||||
Share2,
|
||||
Settings,
|
||||
SunMedium,
|
||||
Trash,
|
||||
@@ -90,7 +92,8 @@ export const Icons = {
|
||||
billing: CreditCard,
|
||||
ellipsis: MoreVertical,
|
||||
add: Plus,
|
||||
play: PlayCircleIcon,
|
||||
play: Play,
|
||||
playCircle: PlayCircleIcon,
|
||||
pause: PauseCircleIcon,
|
||||
warning: AlertTriangle,
|
||||
error: AlertCircle,
|
||||
@@ -106,7 +109,8 @@ export const Icons = {
|
||||
check: Check,
|
||||
copy: Copy,
|
||||
copyDone: ClipboardCheck,
|
||||
save: SunMedium,
|
||||
save: Save,
|
||||
share: Share2,
|
||||
sun: SunMedium,
|
||||
moon: Moon,
|
||||
laptop: Laptop,
|
||||
@@ -134,7 +138,8 @@ export const Icons = {
|
||||
),
|
||||
aria: (props: LucideProps) => (
|
||||
<svg role="img" viewBox="0 0 24 24" fill="currentColor" {...props}>
|
||||
<path d="M13.966 22.624l-1.69-4.281H8.122l3.892-9.144 5.662 13.425zM8.884 1.376H0v21.248zm15.116 0h-8.884L24 22.624Z" />
|
||||
<path
|
||||
d="M13.966 22.624l-1.69-4.281H8.122l3.892-9.144 5.662 13.425zM8.884 1.376H0v21.248zm15.116 0h-8.884L24 22.624Z"/>
|
||||
</svg>
|
||||
),
|
||||
npm: (props: LucideProps) => (
|
||||
|
||||
@@ -135,7 +135,7 @@ const MainPlayer = ({ mix }: IMainPlayerProps) => {
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="flex space-x-0">
|
||||
<Icons.play />
|
||||
<Icons.playCircle />
|
||||
<div className="text-xs">{playCount}</div>
|
||||
</div>
|
||||
<div className="mr-2 space-x-1 text-gray-400">
|
||||
|
||||
@@ -53,7 +53,7 @@ const PlayPauseButton = ({
|
||||
{nowPlaying?.id === mix.id && playState === PlayState.playing ? (
|
||||
<Icons.pause className="h-full w-full" />
|
||||
) : (
|
||||
<Icons.play className="h-full w-full" />
|
||||
<Icons.playCircle className="h-full w-full" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -27,16 +27,16 @@ export const mixRouter = createTRPCRouter({
|
||||
getByUserAndSlug: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
userName: z.string(),
|
||||
username: z.string(),
|
||||
mixSlug: z.string(),
|
||||
})
|
||||
)
|
||||
.query(async ({ input: { userName, mixSlug }, ctx }) => {
|
||||
.query(async ({ input: { username: username, mixSlug }, ctx }) => {
|
||||
//don't like this but it appears we can't query on foreign key columns
|
||||
//in drizzle
|
||||
|
||||
const user = await db.query.users.findFirst({
|
||||
where: (users, { eq }) => eq(users.username, userName),
|
||||
where: (users, { eq }) => eq(users.username, username),
|
||||
});
|
||||
if (!user) {
|
||||
throw new trpc.TRPCError({
|
||||
|
||||
Reference in New Issue
Block a user