Initial user profile page added

This commit is contained in:
Fergal Moran
2023-07-04 20:46:39 +01:00
parent cfab005532
commit 0741dfe0e9
10 changed files with 93 additions and 62 deletions

View File

@@ -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;

View File

@@ -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;

View 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;

View 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;

View File

@@ -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) {

View 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;

View File

@@ -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) => (

View File

@@ -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">

View File

@@ -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>

View File

@@ -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({