mirror of
https://github.com/fergalmoran/mixyboos.git
synced 2025-12-22 09:41:39 +00:00
Routes.
This commit is contained in:
@@ -3,8 +3,8 @@ import * as dotenv from "dotenv";
|
||||
dotenv?.config();
|
||||
|
||||
export default {
|
||||
schema: "./src/schema.ts",
|
||||
out: "./drizzle",
|
||||
schema: "./src/db/schema.ts",
|
||||
out: "./src/db/migrations",
|
||||
driver: "pg",
|
||||
dbCredentials: {
|
||||
connectionString: process.env.DATABASE_URL as string,
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "LiveShowStatus" AS ENUM('SETUP', 'AWAITING', 'STREAMING', 'FINISHED');
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "live_shows" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"slug" varchar(50) NOT NULL,
|
||||
"full_name" text,
|
||||
"description" varchar(256),
|
||||
"status" "LiveShowStatus",
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now(),
|
||||
"user_id" uuid NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "live_show_tags" (
|
||||
"live_show_id" uuid NOT NULL,
|
||||
"tag_id" uuid NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "live_show_tags" ADD CONSTRAINT "live_show_tags_live_show_id_tag_id" PRIMARY KEY("live_show_id","tag_id");
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "mixes" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"slug" varchar(50) NOT NULL,
|
||||
"full_name" text,
|
||||
"description" varchar(2048),
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp DEFAULT now() NOT NULL,
|
||||
"user_id" uuid NOT NULL,
|
||||
"is_processed" boolean DEFAULT false NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "mix_tags" (
|
||||
"mix_id" uuid NOT NULL,
|
||||
"tag_id" uuid NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "mix_tags" ADD CONSTRAINT "mix_tags_mix_id_tag_id" PRIMARY KEY("mix_id","tag_id");
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "tags" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"title" text,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"updated_at" timestamp DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "users" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"username" text NOT NULL,
|
||||
"email" text NOT NULL,
|
||||
"emailVerified" timestamp,
|
||||
"name" varchar(2048),
|
||||
"profileImage" text,
|
||||
"headerImage" text,
|
||||
"password" varchar(1024),
|
||||
"stream_key" varchar(64),
|
||||
"urls" text[]
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "title_idx" ON "tags" ("title");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "username_idx" ON "users" ("username");--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "live_shows" ADD CONSTRAINT "live_shows_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "live_show_tags" ADD CONSTRAINT "live_show_tags_live_show_id_mixes_id_fk" FOREIGN KEY ("live_show_id") REFERENCES "mixes"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "live_show_tags" ADD CONSTRAINT "live_show_tags_tag_id_tags_id_fk" FOREIGN KEY ("tag_id") REFERENCES "tags"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "mixes" ADD CONSTRAINT "mixes_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "mix_tags" ADD CONSTRAINT "mix_tags_mix_id_mixes_id_fk" FOREIGN KEY ("mix_id") REFERENCES "mixes"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "mix_tags" ADD CONSTRAINT "mix_tags_tag_id_tags_id_fk" FOREIGN KEY ("tag_id") REFERENCES "tags"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
@@ -1,408 +0,0 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "pg",
|
||||
"id": "3aa3a733-36d0-4095-a8a5-f3436102791a",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"tables": {
|
||||
"live_shows": {
|
||||
"name": "live_shows",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"full_name": {
|
||||
"name": "full_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "varchar(256)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "LiveShowStatus",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"live_shows_user_id_users_id_fk": {
|
||||
"name": "live_shows_user_id_users_id_fk",
|
||||
"tableFrom": "live_shows",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {}
|
||||
},
|
||||
"live_show_tags": {
|
||||
"name": "live_show_tags",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"live_show_id": {
|
||||
"name": "live_show_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"tag_id": {
|
||||
"name": "tag_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"live_show_tags_live_show_id_mixes_id_fk": {
|
||||
"name": "live_show_tags_live_show_id_mixes_id_fk",
|
||||
"tableFrom": "live_show_tags",
|
||||
"tableTo": "mixes",
|
||||
"columnsFrom": [
|
||||
"live_show_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"live_show_tags_tag_id_tags_id_fk": {
|
||||
"name": "live_show_tags_tag_id_tags_id_fk",
|
||||
"tableFrom": "live_show_tags",
|
||||
"tableTo": "tags",
|
||||
"columnsFrom": [
|
||||
"tag_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"live_show_tags_live_show_id_tag_id": {
|
||||
"name": "live_show_tags_live_show_id_tag_id",
|
||||
"columns": [
|
||||
"live_show_id",
|
||||
"tag_id"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mixes": {
|
||||
"name": "mixes",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"full_name": {
|
||||
"name": "full_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"is_processed": {
|
||||
"name": "is_processed",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"mixes_user_id_users_id_fk": {
|
||||
"name": "mixes_user_id_users_id_fk",
|
||||
"tableFrom": "mixes",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {}
|
||||
},
|
||||
"mix_tags": {
|
||||
"name": "mix_tags",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"mix_id": {
|
||||
"name": "mix_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"tag_id": {
|
||||
"name": "tag_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"mix_tags_mix_id_mixes_id_fk": {
|
||||
"name": "mix_tags_mix_id_mixes_id_fk",
|
||||
"tableFrom": "mix_tags",
|
||||
"tableTo": "mixes",
|
||||
"columnsFrom": [
|
||||
"mix_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"mix_tags_tag_id_tags_id_fk": {
|
||||
"name": "mix_tags_tag_id_tags_id_fk",
|
||||
"tableFrom": "mix_tags",
|
||||
"tableTo": "tags",
|
||||
"columnsFrom": [
|
||||
"tag_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"mix_tags_mix_id_tag_id": {
|
||||
"name": "mix_tags_mix_id_tag_id",
|
||||
"columns": [
|
||||
"mix_id",
|
||||
"tag_id"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": {
|
||||
"name": "tags",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"title_idx": {
|
||||
"name": "title_idx",
|
||||
"columns": [
|
||||
"title"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"emailVerified": {
|
||||
"name": "emailVerified",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"profileImage": {
|
||||
"name": "profileImage",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"headerImage": {
|
||||
"name": "headerImage",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"password": {
|
||||
"name": "password",
|
||||
"type": "varchar(1024)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stream_key": {
|
||||
"name": "stream_key",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"urls": {
|
||||
"name": "urls",
|
||||
"type": "text[]",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"username_idx": {
|
||||
"name": "username_idx",
|
||||
"columns": [
|
||||
"username"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"LiveShowStatus": {
|
||||
"name": "LiveShowStatus",
|
||||
"values": {
|
||||
"SETUP": "SETUP",
|
||||
"AWAITING": "AWAITING",
|
||||
"STREAMING": "STREAMING",
|
||||
"FINISHED": "FINISHED"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "pg",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "5",
|
||||
"when": 1688336894767,
|
||||
"tag": "0000_mysterious_sentinels",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -34,7 +34,7 @@
|
||||
"http-status-codes": "^2.2.0",
|
||||
"import-local": "^3.1.0",
|
||||
"install": "^0.13.0",
|
||||
"next": "13.4.8",
|
||||
"next": "13.4.10-canary.0",
|
||||
"next-auth": "^4.22.1",
|
||||
"pg": "^8.11.1",
|
||||
"postgres": "^3.3.5",
|
||||
|
||||
98
pnpm-lock.yaml
generated
98
pnpm-lock.yaml
generated
@@ -19,7 +19,7 @@ dependencies:
|
||||
version: 1.1.4(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@sentry/nextjs':
|
||||
specifier: ^7.57.0
|
||||
version: 7.57.0(next@13.4.8)(react@18.2.0)
|
||||
version: 7.57.0(next@13.4.10-canary.0)(react@18.2.0)
|
||||
'@sindresorhus/slugify':
|
||||
specifier: ^2.2.1
|
||||
version: 2.2.1
|
||||
@@ -34,7 +34,7 @@ dependencies:
|
||||
version: 10.33.0(@trpc/server@10.33.0)
|
||||
'@trpc/next':
|
||||
specifier: ^10.33.0
|
||||
version: 10.33.0(@tanstack/react-query@4.29.19)(@trpc/client@10.33.0)(@trpc/react-query@10.33.0)(@trpc/server@10.33.0)(next@13.4.8)(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 10.33.0(@tanstack/react-query@4.29.19)(@trpc/client@10.33.0)(@trpc/react-query@10.33.0)(@trpc/server@10.33.0)(next@13.4.10-canary.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/react-query':
|
||||
specifier: ^10.33.0
|
||||
version: 10.33.0(@tanstack/react-query@4.29.19)(@trpc/client@10.33.0)(@trpc/server@10.33.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
@@ -69,11 +69,11 @@ dependencies:
|
||||
specifier: ^0.13.0
|
||||
version: 0.13.0
|
||||
next:
|
||||
specifier: 13.4.8
|
||||
version: 13.4.8(@babel/core@7.22.6)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
specifier: 13.4.10-canary.0
|
||||
version: 13.4.10-canary.0(@babel/core@7.22.6)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
next-auth:
|
||||
specifier: ^4.22.1
|
||||
version: 4.22.1(next@13.4.8)(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 4.22.1(next@13.4.10-canary.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
pg:
|
||||
specifier: ^8.11.1
|
||||
version: 8.11.1
|
||||
@@ -216,7 +216,7 @@ devDependencies:
|
||||
version: 0.258.0(react@18.2.0)
|
||||
next-themes:
|
||||
specifier: ^0.2.1
|
||||
version: 0.2.1(next@13.4.8)(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 0.2.1(next@13.4.10-canary.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
node-mocks-http:
|
||||
specifier: ^1.12.2
|
||||
version: 1.12.2
|
||||
@@ -1788,8 +1788,12 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@next/env@13.4.10-canary.0:
|
||||
resolution: {integrity: sha512-kOEMhom5gCLdtrFXGCrO3qUObPbXMJ0hLavKAEAx0Vme9YaDjYBqLuQUJ9UfpFzjYIXh4t3/ZuSmxnfSPxldZg==}
|
||||
|
||||
/@next/env@13.4.8:
|
||||
resolution: {integrity: sha512-twuSf1klb3k9wXI7IZhbZGtFCWvGD4wXTY2rmvzIgVhXhs7ISThrbNyutBx3jWIL8Y/Hk9+woytFz5QsgtcRKQ==}
|
||||
dev: true
|
||||
|
||||
/@next/eslint-plugin-next@13.4.8:
|
||||
resolution: {integrity: sha512-cmfVHpxWjjcETFt2WHnoFU6EmY69QcPJRlRNAooQlNe53Ke90vg1Ci/dkPffryJZaxxiRziP9bQrV8lDVCn3Fw==}
|
||||
@@ -1797,72 +1801,72 @@ packages:
|
||||
glob: 7.1.7
|
||||
dev: true
|
||||
|
||||
/@next/swc-darwin-arm64@13.4.8:
|
||||
resolution: {integrity: sha512-MSFplVM4dTWOuKAUv0XR9gY7AWtMSBu9os9f+kp+s5rWhM1I2CdR3obFttd6366nS/W/VZxbPM5oEIdlIa46zA==}
|
||||
/@next/swc-darwin-arm64@13.4.10-canary.0:
|
||||
resolution: {integrity: sha512-7fO4zkE2S7XytxRGwCz77tPlVXdJrF0YV6hbgRi2dAkDCwSPKSqLOcwqhd945XhVXAXOyat8nvSG29lQeo8+cw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@next/swc-darwin-x64@13.4.8:
|
||||
resolution: {integrity: sha512-Reox+UXgonon9P0WNDE6w85DGtyBqGitl/ryznOvn6TvfxEaZIpTgeu3ZrJLU9dHSMhiK7YAM793mE/Zii2/Qw==}
|
||||
/@next/swc-darwin-x64@13.4.10-canary.0:
|
||||
resolution: {integrity: sha512-bm5pJejXtNuROmG1xePzmEOiFCBPAQYOBV3d0Jc4UPe8iJMHF0G/REKyaobFds5Oz0rd7O+WUqX4mx8/Mnf/eQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@next/swc-linux-arm64-gnu@13.4.8:
|
||||
resolution: {integrity: sha512-kdyzYvAYtqQVgzIKNN7e1rLU8aZv86FDSRqPlOkKZlvqudvTO0iohuTPmnEEDlECeBM6qRPShNffotDcU/R2KA==}
|
||||
/@next/swc-linux-arm64-gnu@13.4.10-canary.0:
|
||||
resolution: {integrity: sha512-u4OtqbLYW2srSsybJrc4Dv2m+iJy9trAzUApPfRkV9KbOPKhne4oHwziKfoRIfgBdQdVacbZ/kl02hn7VWgoeQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@next/swc-linux-arm64-musl@13.4.8:
|
||||
resolution: {integrity: sha512-oWxx4yRkUGcR81XwbI+T0zhZ3bDF6V1aVLpG+C7hSG50ULpV8gC39UxVO22/bv93ZlcfMY4zl8xkz9Klct6dpQ==}
|
||||
/@next/swc-linux-arm64-musl@13.4.10-canary.0:
|
||||
resolution: {integrity: sha512-VxZ1etsSaL507WQ6xQAdaGju3ueFR623wi/1/ZxWxfGGPqyPn2LwL2Fbx8PDLv9gH6EKZdQG8lRXdUlV/LVPLw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@next/swc-linux-x64-gnu@13.4.8:
|
||||
resolution: {integrity: sha512-anhtvuO6eE9YRhYnaEGTfbpH3L5gT/9qPFcNoi6xS432r/4DAtpJY8kNktqkTVevVIC/pVumqO8tV59PR3zbNg==}
|
||||
/@next/swc-linux-x64-gnu@13.4.10-canary.0:
|
||||
resolution: {integrity: sha512-zHSMxQtk+lH/TjY7O6vZjHPA/fE258tHA3MCbzSYMTFwFRwOS5T3bUu/9I6GLRVzVJb2EVPEtSBJKAFdwBttYA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@next/swc-linux-x64-musl@13.4.8:
|
||||
resolution: {integrity: sha512-aR+J4wWfNgH1DwCCBNjan7Iumx0lLtn+2/rEYuhIrYLY4vnxqSVGz9u3fXcgUwo6Q9LT8NFkaqK1vPprdq+BXg==}
|
||||
/@next/swc-linux-x64-musl@13.4.10-canary.0:
|
||||
resolution: {integrity: sha512-FC50Pvfy0v/FB84DfSSgESrhUUxeqCMkLpIkjMCCwOoaGiMc9RjToOjT5OZj2M1dik472MKdpKkh1+sou+7CUw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@next/swc-win32-arm64-msvc@13.4.8:
|
||||
resolution: {integrity: sha512-OWBKIrJwQBTqrat0xhxEB/jcsjJR3+diD9nc/Y8F1mRdQzsn4bPsomgJyuqPVZs6Lz3K18qdIkvywmfSq75SsQ==}
|
||||
/@next/swc-win32-arm64-msvc@13.4.10-canary.0:
|
||||
resolution: {integrity: sha512-W/GV3UusZZczoDimCJWTxXQk62iwAAjDuVvISSLXuxuOGrRuJkHaRQQnTsN7pECRANDRIBiGDecawMuWz1iFOw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@next/swc-win32-ia32-msvc@13.4.8:
|
||||
resolution: {integrity: sha512-agiPWGjUndXGTOn4ChbKipQXRA6/UPkywAWIkx7BhgGv48TiJfHTK6MGfBoL9tS6B4mtW39++uy0wFPnfD0JWg==}
|
||||
/@next/swc-win32-ia32-msvc@13.4.10-canary.0:
|
||||
resolution: {integrity: sha512-LBbVkr3DaC8YWndxBUk22BbXRPd2OEjP40u/lpQQZnYQBiAHRBH7GRaPUOyTR1uSAjsmwKKtGPD6GYkn1nWOtg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@next/swc-win32-x64-msvc@13.4.8:
|
||||
resolution: {integrity: sha512-UIRKoByVKbuR6SnFG4JM8EMFlJrfEGuUQ1ihxzEleWcNwRMMiVaCj1KyqfTOW8VTQhJ0u8P1Ngg6q1RwnIBTtw==}
|
||||
/@next/swc-win32-x64-msvc@13.4.10-canary.0:
|
||||
resolution: {integrity: sha512-jk5naKdJ0M7Bv3NRRysJu8sKDKsUqvUZYVjTyKPSYv0dKU0sdLsCO/gOcvi+Zs1i8vkS6h+yIrKxMyvM++CNGQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@@ -2713,7 +2717,7 @@ packages:
|
||||
tslib: 2.6.0
|
||||
dev: false
|
||||
|
||||
/@sentry/nextjs@7.57.0(next@13.4.8)(react@18.2.0):
|
||||
/@sentry/nextjs@7.57.0(next@13.4.10-canary.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-TH7Hhs833j1k2rM5K3AqiQ7+bxrTzANZazBLEK1YVec02PpnqflVuBHSdFxT6dG7ypxOpMkN36BN5INY5HHT0Q==}
|
||||
engines: {node: '>=8'}
|
||||
peerDependencies:
|
||||
@@ -2733,7 +2737,7 @@ packages:
|
||||
'@sentry/utils': 7.57.0
|
||||
'@sentry/webpack-plugin': 1.20.0
|
||||
chalk: 3.0.0
|
||||
next: 13.4.8(@babel/core@7.22.6)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
next: 13.4.10-canary.0(@babel/core@7.22.6)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
react: 18.2.0
|
||||
rollup: 2.78.0
|
||||
stacktrace-parser: 0.1.10
|
||||
@@ -2905,7 +2909,7 @@ packages:
|
||||
'@trpc/server': 10.33.0
|
||||
dev: false
|
||||
|
||||
/@trpc/next@10.33.0(@tanstack/react-query@4.29.19)(@trpc/client@10.33.0)(@trpc/react-query@10.33.0)(@trpc/server@10.33.0)(next@13.4.8)(react-dom@18.2.0)(react@18.2.0):
|
||||
/@trpc/next@10.33.0(@tanstack/react-query@4.29.19)(@trpc/client@10.33.0)(@trpc/react-query@10.33.0)(@trpc/server@10.33.0)(next@13.4.10-canary.0)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-x2aRwGbXd+8Yk3WxVGF5IDWu9f/m2Na68FTU7df8WoJ4Il8T79Blr3i2CrpGrLZ25KyAJ34Mpqtaxwb1dUct0g==}
|
||||
peerDependencies:
|
||||
'@tanstack/react-query': ^4.18.0
|
||||
@@ -2920,7 +2924,7 @@ packages:
|
||||
'@trpc/client': 10.33.0(@trpc/server@10.33.0)
|
||||
'@trpc/react-query': 10.33.0(@tanstack/react-query@4.29.19)(@trpc/client@10.33.0)(@trpc/server@10.33.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/server': 10.33.0
|
||||
next: 13.4.8(@babel/core@7.22.6)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
next: 13.4.10-canary.0(@babel/core@7.22.6)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
react-ssr-prepass: 1.5.0(react@18.2.0)
|
||||
@@ -3833,7 +3837,7 @@ packages:
|
||||
hasBin: true
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001512
|
||||
electron-to-chromium: 1.4.449
|
||||
electron-to-chromium: 1.4.450
|
||||
node-releases: 2.0.12
|
||||
update-browserslist-db: 1.0.11(browserslist@4.21.9)
|
||||
|
||||
@@ -4706,8 +4710,8 @@ packages:
|
||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||
dev: false
|
||||
|
||||
/electron-to-chromium@1.4.449:
|
||||
resolution: {integrity: sha512-TxLRpRUj/107ATefeP8VIUWNOv90xJxZZbCW/eIbSZQiuiFANCx2b7u+GbVc9X4gU+xnbvypNMYVM/WArE1DNQ==}
|
||||
/electron-to-chromium@1.4.450:
|
||||
resolution: {integrity: sha512-BLG5HxSELlrMx7dJ2s+8SFlsCtJp37Zpk2VAxyC6CZtbc+9AJeZHfYHbrlSgdXp6saQ8StMqOTEDaBKgA7u1sw==}
|
||||
|
||||
/emittery@0.13.1:
|
||||
resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
|
||||
@@ -7224,7 +7228,7 @@ packages:
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: true
|
||||
|
||||
/next-auth@4.22.1(next@13.4.8)(react-dom@18.2.0)(react@18.2.0):
|
||||
/next-auth@4.22.1(next@13.4.10-canary.0)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-NTR3f6W7/AWXKw8GSsgSyQcDW6jkslZLH8AiZa5PQ09w1kR8uHtR9rez/E9gAq/o17+p0JYHE8QjF3RoniiObA==}
|
||||
peerDependencies:
|
||||
next: ^12.2.5 || ^13
|
||||
@@ -7239,7 +7243,7 @@ packages:
|
||||
'@panva/hkdf': 1.1.1
|
||||
cookie: 0.5.0
|
||||
jose: 4.14.4
|
||||
next: 13.4.8(@babel/core@7.22.6)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
next: 13.4.10-canary.0(@babel/core@7.22.6)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
oauth: 0.9.15
|
||||
openid-client: 5.4.2
|
||||
preact: 10.15.1
|
||||
@@ -7249,14 +7253,14 @@ packages:
|
||||
uuid: 8.3.2
|
||||
dev: false
|
||||
|
||||
/next-themes@0.2.1(next@13.4.8)(react-dom@18.2.0)(react@18.2.0):
|
||||
/next-themes@0.2.1(next@13.4.10-canary.0)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==}
|
||||
peerDependencies:
|
||||
next: '*'
|
||||
react: '*'
|
||||
react-dom: '*'
|
||||
dependencies:
|
||||
next: 13.4.8(@babel/core@7.22.6)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
next: 13.4.10-canary.0(@babel/core@7.22.6)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: true
|
||||
@@ -7265,8 +7269,8 @@ packages:
|
||||
resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==}
|
||||
dev: true
|
||||
|
||||
/next@13.4.8(@babel/core@7.22.6)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-lxUjndYKjZHGK3CWeN2RI+/6ni6EUvjiqGWXAYPxUfGIdFGQ5XoisrqAJ/dF74aP27buAfs8MKIbIMMdxjqSBg==}
|
||||
/next@13.4.10-canary.0(@babel/core@7.22.6)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-bi/HYZSeMtDjH3wNBCWpwaRJEX6K/opCCVd9shrMv79ERP+Npw6i5al7MuWCTC7yY3IAbpOG7WgTsYgnoBtnGg==}
|
||||
engines: {node: '>=16.8.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -7283,7 +7287,7 @@ packages:
|
||||
sass:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@next/env': 13.4.8
|
||||
'@next/env': 13.4.10-canary.0
|
||||
'@opentelemetry/api': 1.4.1
|
||||
'@swc/helpers': 0.5.1
|
||||
busboy: 1.6.0
|
||||
@@ -7295,15 +7299,15 @@ packages:
|
||||
watchpack: 2.4.0
|
||||
zod: 3.21.4
|
||||
optionalDependencies:
|
||||
'@next/swc-darwin-arm64': 13.4.8
|
||||
'@next/swc-darwin-x64': 13.4.8
|
||||
'@next/swc-linux-arm64-gnu': 13.4.8
|
||||
'@next/swc-linux-arm64-musl': 13.4.8
|
||||
'@next/swc-linux-x64-gnu': 13.4.8
|
||||
'@next/swc-linux-x64-musl': 13.4.8
|
||||
'@next/swc-win32-arm64-msvc': 13.4.8
|
||||
'@next/swc-win32-ia32-msvc': 13.4.8
|
||||
'@next/swc-win32-x64-msvc': 13.4.8
|
||||
'@next/swc-darwin-arm64': 13.4.10-canary.0
|
||||
'@next/swc-darwin-x64': 13.4.10-canary.0
|
||||
'@next/swc-linux-arm64-gnu': 13.4.10-canary.0
|
||||
'@next/swc-linux-arm64-musl': 13.4.10-canary.0
|
||||
'@next/swc-linux-x64-gnu': 13.4.10-canary.0
|
||||
'@next/swc-linux-x64-musl': 13.4.10-canary.0
|
||||
'@next/swc-win32-arm64-msvc': 13.4.10-canary.0
|
||||
'@next/swc-win32-ia32-msvc': 13.4.10-canary.0
|
||||
'@next/swc-win32-x64-msvc': 13.4.10-canary.0
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- babel-plugin-macros
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 129 KiB |
@@ -1,19 +0,0 @@
|
||||
"use client";
|
||||
import Sidebar from "@/lib/components/layout/sidebar/Sidebar";
|
||||
import Loading from "@/lib/components/widgets/Loading";
|
||||
import { useSession } from "next-auth/react";
|
||||
import React from "react";
|
||||
|
||||
const DashboardLayout = ({ children }: { children: React.ReactNode }) => {
|
||||
const { data: session, status } = useSession();
|
||||
|
||||
if (!session) return <Loading />;
|
||||
return (
|
||||
<div className="mx-20 -mb-16 flex h-screen overflow-hidden">
|
||||
<Sidebar session={session} />
|
||||
<div className="w-full">{children}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardLayout;
|
||||
@@ -1,150 +0,0 @@
|
||||
import { Icons } from "@/components/icons";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import FollowersGraph from "@/components/widgets/stats/followers-graph";
|
||||
import PlaysGraph from "@/components/widgets/stats/plays-graph";
|
||||
import Image from "next/image";
|
||||
import React from "react";
|
||||
|
||||
type DashboardPageProps = {
|
||||
prop1: string;
|
||||
};
|
||||
|
||||
const DashboardPage = ({ prop1 }: DashboardPageProps) => {
|
||||
return (
|
||||
<>
|
||||
<div className="md:hidden">
|
||||
<Image
|
||||
src="/img/dashboard-light.png"
|
||||
width={1280}
|
||||
height={866}
|
||||
alt="Dashboard"
|
||||
className="block dark:hidden"
|
||||
/>
|
||||
<Image
|
||||
src="/img/dashboard-dark.png"
|
||||
width={1280}
|
||||
height={866}
|
||||
alt="Dashboard"
|
||||
className="hidden dark:block"
|
||||
/>
|
||||
</div>
|
||||
<div className="hidden flex-col md:flex">
|
||||
<div className="flex-1 space-y-4 p-8 pt-6">
|
||||
<div className="flex items-center justify-between space-y-2">
|
||||
<h2 className="text-3xl font-bold tracking-tight">Dashboard</h2>
|
||||
<div className="flex items-center space-x-2">
|
||||
{/* <CalendarDateRangePicker /> */}
|
||||
<Button size="sm">
|
||||
<Icons.download className="mr-2 h-4 w-4" />
|
||||
Download
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Tabs defaultValue="overview" className="space-y-4">
|
||||
<TabsList>
|
||||
<TabsTrigger value="overview">Overview</TabsTrigger>
|
||||
<TabsTrigger value="analytics" disabled>
|
||||
Analytics
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="reports" disabled>
|
||||
Reports
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="notifications" disabled>
|
||||
Notifications
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="overview" className="space-y-4">
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">
|
||||
Total Revenue
|
||||
</CardTitle>
|
||||
<Icons.money className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">$45,231.89</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+20.1% from last month
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">
|
||||
Subscriptions
|
||||
</CardTitle>
|
||||
<Icons.users className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">+2350</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+180.1% from last month
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Sales</CardTitle>
|
||||
<Icons.billing className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">+12,234</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+19% from last month
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">
|
||||
Active Now
|
||||
</CardTitle>
|
||||
<Icons.activity className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">+573</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+201 since last hour
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-7">
|
||||
<Card className="col-span-4">
|
||||
<CardHeader>
|
||||
<CardTitle>Plays</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="pl-2">
|
||||
<PlaysGraph />
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="col-span-3">
|
||||
<CardHeader>
|
||||
<CardTitle>Recent Sales</CardTitle>
|
||||
<CardDescription>
|
||||
You made 265 sales this month.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<FollowersGraph />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardPage;
|
||||
@@ -1,12 +0,0 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { api } from "@/lib/utils/api";
|
||||
import LiveShowWrapper from "@/lib/components/show/LiveShowWrapper";
|
||||
import Loading from "@/lib/components/widgets/Loading";
|
||||
|
||||
const LivePage = () => {
|
||||
const { isFetching, data: show } = api.show.getInProgress.useQuery();
|
||||
return isFetching ? <Loading /> : <LiveShowWrapper incomingShow={show} />;
|
||||
};
|
||||
|
||||
export default LivePage;
|
||||
@@ -1,13 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const LiveLayout = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
// padding-top: 24px;
|
||||
// padding-right: 128px;
|
||||
// padding-bottom: 24px;
|
||||
// padding-left: 128px;
|
||||
<div className="px-28 py-6">{children}</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LiveLayout;
|
||||
@@ -1,8 +0,0 @@
|
||||
import MixCreateComponent from "@/lib/components/mix/create/MixCreateComponent";
|
||||
import React from "react";
|
||||
|
||||
const MixCreatePage = () => {
|
||||
return <MixCreateComponent />;
|
||||
};
|
||||
|
||||
export default MixCreatePage;
|
||||
@@ -1,5 +0,0 @@
|
||||
const ProfileForm = () => {
|
||||
return <h1>Account Form</h1>;
|
||||
};
|
||||
|
||||
export default ProfileForm;
|
||||
@@ -1,22 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import Loading from "@/lib/components/widgets/Loading";
|
||||
import { api } from "@/lib/utils/api";
|
||||
import React from "react";
|
||||
import ProfileImageEditForm from "../../components/profile-images-form";
|
||||
|
||||
const ProfileImagesPage = () => {
|
||||
const { data: profile, status } = api.user.getProfileForSettings.useQuery();
|
||||
|
||||
if (status === "loading") {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
if (!profile) {
|
||||
return <h1>{"Can't find your profile"}</h1>;
|
||||
}
|
||||
|
||||
return <ProfileImageEditForm profile={profile} />;
|
||||
};
|
||||
|
||||
export default ProfileImagesPage;
|
||||
@@ -1,5 +0,0 @@
|
||||
const NotificationsForm = () => {
|
||||
return <h1>Notifications Form</h1>;
|
||||
};
|
||||
|
||||
export default NotificationsForm;
|
||||
@@ -1,22 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import Loading from "@/lib/components/widgets/Loading";
|
||||
import { api } from "@/lib/utils/api";
|
||||
import { type NextPage } from "next";
|
||||
import React from "react";
|
||||
import ProfileEditForm from "../../components/profile-edit-form";
|
||||
|
||||
const ProfileSettingsPage: NextPage = () => {
|
||||
const { data: profile, status } = api.user.getProfileForSettings.useQuery();
|
||||
|
||||
if (status === "loading") {
|
||||
return <Loading />;
|
||||
}
|
||||
return profile ? (
|
||||
<ProfileEditForm profile={profile} />
|
||||
) : (
|
||||
<div>Nothing here bai!</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProfileSettingsPage;
|
||||
@@ -1,181 +0,0 @@
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormDescription,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/form";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { toast } from "@/components/ui/use-toast";
|
||||
import { notice } from "@/lib/components/notifications/toast";
|
||||
import { type UserModel } from "@/lib/models";
|
||||
import { api } from "@/lib/utils/api";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import React from "react";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
|
||||
type ProfileEditFormProps = {
|
||||
profile: UserModel;
|
||||
};
|
||||
const formSchema = z.object({
|
||||
username: z
|
||||
.string()
|
||||
.min(2, {
|
||||
message: "Username must be at least 2 characters.",
|
||||
})
|
||||
.max(30, {
|
||||
message: "Username must not be longer than 30 characters.",
|
||||
}),
|
||||
email: z.string().email(),
|
||||
bio: z.string().max(160).min(0).nullable(),
|
||||
urls: z
|
||||
.array(
|
||||
z.object({
|
||||
value: z.string().url({ message: "Please enter a valid URL." }),
|
||||
})
|
||||
)
|
||||
.optional(),
|
||||
});
|
||||
type FormValues = z.infer<typeof formSchema>;
|
||||
|
||||
const ProfileEditForm: React.FC<ProfileEditFormProps> = ({
|
||||
profile,
|
||||
}: ProfileEditFormProps) => {
|
||||
const updateUser = api.user.updateUser.useMutation({
|
||||
onSuccess: (result) => {
|
||||
console.log("profile-edit-form", "onSuccess", result);
|
||||
notice("Success", "Profile updated successfully");
|
||||
},
|
||||
});
|
||||
const defaultValues: Partial<FormValues> = {
|
||||
username: profile.username,
|
||||
email: profile.email || "",
|
||||
bio: profile.bio || "",
|
||||
urls: [],
|
||||
};
|
||||
const form = useForm<FormValues>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues,
|
||||
mode: "onChange",
|
||||
});
|
||||
|
||||
const { fields, append } = useFieldArray({
|
||||
name: "urls",
|
||||
control: form.control,
|
||||
});
|
||||
|
||||
const onSubmit = async (data: FormValues) => {
|
||||
console.log("profile-edit-form", "onSubmit", data);
|
||||
await updateUser.mutateAsync({
|
||||
...profile,
|
||||
username: data.username,
|
||||
email: data.email,
|
||||
bio: data.bio,
|
||||
urls: [],
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="username" {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
This is your public display name. It can be your real name or a
|
||||
pseudonym. You can only change this once every 30 days.
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Email</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="me@gmail.com" {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
How we get in touch with you, we will never share or sell your
|
||||
email address
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="bio"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Bio</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea
|
||||
placeholder="Tell us a little bit about yourself"
|
||||
className="resize-none"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
You can <span>@mention</span> other users and organizations to
|
||||
link to them.
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<div>
|
||||
{fields.map((field, index) => (
|
||||
<FormField
|
||||
control={form.control}
|
||||
key={field.id}
|
||||
name={`urls.${index}.value`}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel className={cn(index !== 0 && "sr-only")}>
|
||||
URLs
|
||||
</FormLabel>
|
||||
<FormDescription className={cn(index !== 0 && "sr-only")}>
|
||||
Add links to your website, blog, or social media profiles.
|
||||
</FormDescription>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
<Button
|
||||
type="button"
|
||||
variant="link"
|
||||
size="sm"
|
||||
className="mt-1"
|
||||
onClick={() => append({ value: "" })}
|
||||
>
|
||||
Add URL
|
||||
</Button>
|
||||
</div>
|
||||
<Button type="submit">Update profile</Button>
|
||||
</form>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProfileEditForm;
|
||||
@@ -1,218 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Form,
|
||||
FormDescription,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/form";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import ImageUpload from "@/components/widgets/image-upload";
|
||||
import { notice } from "@/lib/components/notifications/toast";
|
||||
import { type UserModel } from "@/lib/models";
|
||||
import { uploadFile } from "@/lib/services/azure/upload";
|
||||
import { getFileExtension } from "@/lib/utils/fileUtils";
|
||||
import { api } from "@/lib/utils/api";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useSession } from "next-auth/react";
|
||||
import React from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
|
||||
const MAX_PROFILE_IMAGE_SIZE = 5242880;
|
||||
const ACCEPTED_IMAGE_TYPES = [
|
||||
"image/jpeg",
|
||||
"image/jpg",
|
||||
"image/png",
|
||||
"image/webp",
|
||||
];
|
||||
|
||||
type ProfileImageEditFormProps = {
|
||||
profile: UserModel;
|
||||
};
|
||||
|
||||
const ProfileImageEditForm: React.FC<ProfileImageEditFormProps> = ({
|
||||
profile,
|
||||
}) => {
|
||||
const { update } = useSession();
|
||||
|
||||
const [profileImageChanged, setProfileImageChanged] = React.useState(false);
|
||||
const [headerImageChanged, setHeaderImageChanged] = React.useState(false);
|
||||
|
||||
const uploader = api.upload.getSASToken.useQuery({ containerName: "images" });
|
||||
const updateUser = api.user.updateUser.useMutation({
|
||||
onSuccess: (result) => {
|
||||
console.log("profile-edit-form", "onSuccess", result);
|
||||
notice("Success", "Profile updated successfully");
|
||||
},
|
||||
});
|
||||
const formSchema = z.object({
|
||||
profileImage: z
|
||||
.any()
|
||||
.refine((file: File) => {
|
||||
const ret =
|
||||
!profileImageChanged || file?.size <= MAX_PROFILE_IMAGE_SIZE;
|
||||
console.log("profile-images-form", "profileImage_refine", ret);
|
||||
return ret;
|
||||
}, `Max image size is 5MB.`)
|
||||
.refine(
|
||||
(file: File) =>
|
||||
!profileImageChanged || ACCEPTED_IMAGE_TYPES.includes(file?.type),
|
||||
"Only .jpg, .jpeg, .png and .webp formats are supported."
|
||||
)
|
||||
.optional(),
|
||||
headerImage: z
|
||||
.any()
|
||||
.refine((file: File) => {
|
||||
const ret =
|
||||
!headerImageChanged || file?.size <= MAX_PROFILE_IMAGE_SIZE * 3;
|
||||
return ret;
|
||||
}, `Max image size is 15MB.`)
|
||||
.refine(
|
||||
(file: File) =>
|
||||
!headerImageChanged || ACCEPTED_IMAGE_TYPES.includes(file?.type),
|
||||
"Only .jpg, .jpeg, .png and .webp formats are supported."
|
||||
)
|
||||
.optional(),
|
||||
});
|
||||
type FormValues = z.infer<typeof formSchema>;
|
||||
|
||||
const defaultValues: Partial<FormValues> = {
|
||||
profileImage: profile.profileImage,
|
||||
headerImage: profile.headerImage,
|
||||
};
|
||||
const form = useForm<FormValues>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues,
|
||||
mode: "onChange",
|
||||
});
|
||||
const onSubmit = async (data: FormValues) => {
|
||||
console.log("profile-images-form", "onSubmit", data);
|
||||
if (profileImageChanged || headerImageChanged) {
|
||||
const token = uploader.data;
|
||||
if (!token) {
|
||||
notice("Error", "Unable to upload at this time");
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
profileImageChanged &&
|
||||
data.profileImage &&
|
||||
data.profileImage instanceof File
|
||||
) {
|
||||
const image = await uploadFile(
|
||||
data.profileImage,
|
||||
"images",
|
||||
`profile/avatars/${profile.id}.${getFileExtension(
|
||||
data.profileImage.name
|
||||
)}`,
|
||||
token
|
||||
);
|
||||
if (image) {
|
||||
await updateUser.mutateAsync({
|
||||
...profile,
|
||||
profileImage: image,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (
|
||||
headerImageChanged &&
|
||||
data.headerImage &&
|
||||
data.headerImage instanceof File
|
||||
) {
|
||||
const image = await uploadFile(
|
||||
data.headerImage,
|
||||
"images",
|
||||
`profile/headers/${profile.id}.${getFileExtension(
|
||||
data.headerImage.name
|
||||
)}`,
|
||||
token
|
||||
);
|
||||
if (image) {
|
||||
await updateUser.mutateAsync({
|
||||
...profile,
|
||||
headerImage: image,
|
||||
});
|
||||
}
|
||||
}
|
||||
await update();
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Form {...form}>
|
||||
{/* <p>{JSON.stringify(form.formState.errors, null, 2)}</p> */}
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="profileImage"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Profile Image</FormLabel>
|
||||
<div className="w-1/2">
|
||||
<Controller
|
||||
control={form.control}
|
||||
name={"profileImage"}
|
||||
rules={{ required: "Gonna need a profile image" }}
|
||||
render={({ field: { value, onChange, ...field } }) => {
|
||||
return (
|
||||
<ImageUpload
|
||||
{...field}
|
||||
imageUrl={value as string}
|
||||
onImageChanged={(image) => {
|
||||
setProfileImageChanged(true);
|
||||
onChange(image);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<FormDescription>
|
||||
{
|
||||
"This is your avatar, it's how you will be recognised on the site"
|
||||
}
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="headerImage"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Header Image</FormLabel>
|
||||
<Controller
|
||||
control={form.control}
|
||||
name={"headerImage"}
|
||||
render={({ field: { value, onChange, ...field } }) => {
|
||||
return (
|
||||
<ImageUpload
|
||||
{...field}
|
||||
className="w-full"
|
||||
imageUrl={value as string}
|
||||
onImageChanged={(image) => {
|
||||
setHeaderImageChanged(true);
|
||||
onChange(image);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormDescription>
|
||||
This is the image that will show at the top of your profile
|
||||
page.
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<Button type="submit">Update profile images</Button>
|
||||
</form>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProfileImageEditForm;
|
||||
@@ -1,44 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface SidebarNavProps extends React.HTMLAttributes<HTMLElement> {
|
||||
items: {
|
||||
href: string;
|
||||
title: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
export function SidebarNav({ className, items, ...props }: SidebarNavProps) {
|
||||
const pathname = usePathname();
|
||||
|
||||
return (
|
||||
<nav
|
||||
className={cn(
|
||||
"flex space-x-2 lg:flex-col lg:space-x-0 lg:space-y-1",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{items.map((item) => (
|
||||
<Link
|
||||
key={item.href}
|
||||
href={item.href}
|
||||
className={cn(
|
||||
buttonVariants({ variant: "ghost" }),
|
||||
pathname === item.href
|
||||
? "bg-muted hover:bg-muted"
|
||||
: "hover:bg-transparent hover:underline",
|
||||
"justify-start"
|
||||
)}
|
||||
>
|
||||
{item.title}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { type Metadata } from "next";
|
||||
import Image from "next/image";
|
||||
import { SidebarNav } from "./components/sidebar-nav";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Forms",
|
||||
description: "Advanced form example using react-hook-form and Zod.",
|
||||
};
|
||||
|
||||
const sidebarNavItems = [
|
||||
{
|
||||
title: "Profile",
|
||||
href: "/settings/profile",
|
||||
},
|
||||
{
|
||||
title: "Images",
|
||||
href: "/settings/images",
|
||||
},
|
||||
{
|
||||
title: "Account",
|
||||
href: "/settings/account",
|
||||
},
|
||||
{
|
||||
title: "Notifications",
|
||||
href: "/settings/notifications",
|
||||
},
|
||||
];
|
||||
|
||||
interface SettingsLayoutProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function SettingsLayout({ children }: SettingsLayoutProps) {
|
||||
return (
|
||||
<div className="mx-auto max-w-5xl">
|
||||
<div className="md:hidden">
|
||||
<Image
|
||||
src="/examples/forms-light.png"
|
||||
width={1280}
|
||||
height={791}
|
||||
alt="Forms"
|
||||
className="block dark:hidden"
|
||||
/>
|
||||
<Image
|
||||
src="/examples/forms-dark.png"
|
||||
width={1280}
|
||||
height={791}
|
||||
alt="Forms"
|
||||
className="hidden dark:block"
|
||||
/>
|
||||
</div>
|
||||
<div className="hidden space-y-6 p-10 pb-16 md:block">
|
||||
<div className="space-y-0.5">
|
||||
<h2 className="text-2xl font-bold tracking-tight">Settings</h2>
|
||||
<p className="text-muted-foreground">Manage your account settings.</p>
|
||||
</div>
|
||||
<Separator className="my-6" />
|
||||
<div className="flex flex-col space-y-8 lg:flex-row lg:space-x-12 lg:space-y-0">
|
||||
<aside className="-mx-4 lg:w-1/5">
|
||||
<SidebarNav items={sidebarNavItems} />
|
||||
</aside>
|
||||
<div className="flex-1 lg:max-w-2xl">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export default function SettingsProfilePage() {
|
||||
return <h1>I am a page</h1>;
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import { db } from "@/server/db";
|
||||
import raise from "@/lib/utils/errors";
|
||||
import { mapDbAuthUserToUserModel } from "@/lib/utils/mappers/userMapper";
|
||||
import { mapMixToMixModel } from "@/lib/utils/mappers/mixMapper";
|
||||
|
||||
async function getData(username: string) {
|
||||
const user = await db.query.users.findFirst({
|
||||
@@ -9,7 +11,19 @@ async function getData(username: string) {
|
||||
if (!user) {
|
||||
return raise("User not found");
|
||||
}
|
||||
return user;
|
||||
|
||||
const mixes = await db.query.mixes.findMany({
|
||||
where: (mixes, { eq }) => eq(mixes.userId, user.id),
|
||||
limit: 10,
|
||||
with: {
|
||||
user: {},
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
user: mapDbAuthUserToUserModel(user),
|
||||
mixes: mixes.map((m) => mapMixToMixModel(m)),
|
||||
};
|
||||
}
|
||||
|
||||
export default getData;
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
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;
|
||||
@@ -1,73 +1,73 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 240 10% 3.9%;
|
||||
|
||||
|
||||
--muted: 240 4.8% 95.9%;
|
||||
--muted-foreground: 240 3.8% 46.1%;
|
||||
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 240 10% 3.9%;
|
||||
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 240 10% 3.9%;
|
||||
|
||||
|
||||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
|
||||
|
||||
--primary: 240 5.9% 10%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
|
||||
|
||||
--secondary: 240 4.8% 95.9%;
|
||||
--secondary-foreground: 240 5.9% 10%;
|
||||
|
||||
|
||||
--accent: 240 4.8% 95.9%;
|
||||
--accent-foreground: 240 5.9% 10%;
|
||||
|
||||
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
|
||||
|
||||
--ring: 240 5% 64.9%;
|
||||
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
|
||||
.dark {
|
||||
--background: 240 10% 3.9%;
|
||||
--foreground: 0 0% 98%;
|
||||
|
||||
|
||||
--muted: 240 3.7% 15.9%;
|
||||
--muted-foreground: 240 5% 64.9%;
|
||||
|
||||
|
||||
--popover: 240 10% 3.9%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
|
||||
|
||||
--card: 240 10% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
|
||||
|
||||
--border: 240 3.7% 15.9%;
|
||||
--input: 240 3.7% 15.9%;
|
||||
|
||||
|
||||
--primary: 0 0% 98%;
|
||||
--primary-foreground: 240 5.9% 10%;
|
||||
|
||||
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
|
||||
|
||||
--accent: 240 3.7% 15.9%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 85.7% 97.3%;
|
||||
|
||||
|
||||
--ring: 240 3.7% 15.9%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
@@ -75,4 +75,4 @@
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ const RootLayout = ({children}: { children: React.ReactNode }) => {
|
||||
<div className="border-b bg-background/95 backdrop-blur">
|
||||
<Navbar className="mx-6"/>
|
||||
</div>
|
||||
<div className="flex-1 space-y-4 p-8 pt-6">{children}</div>
|
||||
<div className="flex-1">{children}</div>
|
||||
</div>
|
||||
</Providers>
|
||||
</body>
|
||||
|
||||
@@ -49,6 +49,7 @@ import {
|
||||
Repeat2,
|
||||
Play,
|
||||
PlayCircle,
|
||||
Mail,
|
||||
} from "lucide-react";
|
||||
|
||||
export type Icon = LucideIcon;
|
||||
@@ -91,6 +92,7 @@ export const Icons = {
|
||||
settings: Settings,
|
||||
billing: CreditCard,
|
||||
ellipsis: MoreVertical,
|
||||
follow: UserPlus,
|
||||
add: Plus,
|
||||
play: Play,
|
||||
playCircle: PlayCircleIcon,
|
||||
@@ -113,6 +115,7 @@ export const Icons = {
|
||||
share: Share2,
|
||||
sun: SunMedium,
|
||||
moon: Moon,
|
||||
message: Mail,
|
||||
laptop: Laptop,
|
||||
upload: UploadCloud,
|
||||
gitHub: (props: LucideProps) => (
|
||||
@@ -138,8 +141,7 @@ 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) => (
|
||||
|
||||
@@ -101,7 +101,7 @@ export const users = pgTable(
|
||||
email: text("email").notNull(),
|
||||
emailVerified: timestamp("emailVerified"),
|
||||
name: text("name"),
|
||||
bio: varchar("name", { length: 2048 }),
|
||||
bio: varchar("bio", { length: 2048 }),
|
||||
profileImage: text("profileImage"),
|
||||
headerImage: text("headerImage"),
|
||||
password: varchar("password", { length: 1024 }),
|
||||
|
||||
@@ -44,8 +44,8 @@ const NavLink = ({ href, title, Icon }: NavLinkProps) => {
|
||||
<Link
|
||||
href={href}
|
||||
className={cn(
|
||||
"text-sm font-medium lowercase text-primary hover:opacity-60 transition-opacity",
|
||||
path !== href && "text-primary"
|
||||
"text-sm font-medium lowercase text-primary-foreground hover:opacity-60 transition-opacity",
|
||||
path !== href && "text-primary-foreground"
|
||||
)}
|
||||
>
|
||||
<div className="inline-flex items-center">
|
||||
|
||||
@@ -37,7 +37,11 @@ const DashboardSidebar = ({ session }: DashboardSidebarProps) => {
|
||||
<div className="h-full w-60 space-y-2 p-3 ">
|
||||
<div className="flex items-center space-x-4 p-2">
|
||||
{session.user.profileImage && (
|
||||
<UserImage src={session.user.profileImage} status={"offline"} size={"md"} />
|
||||
<UserImage
|
||||
src={session.user.profileImage}
|
||||
status={"offline"}
|
||||
size={"md"}
|
||||
/>
|
||||
)}
|
||||
<div>
|
||||
<h2 className="text-sm font-semibold">
|
||||
@@ -59,7 +63,7 @@ const DashboardSidebar = ({ session }: DashboardSidebarProps) => {
|
||||
<li className="">
|
||||
<Link
|
||||
rel="noopener noreferrer"
|
||||
href="dashboard/shows"
|
||||
href={`${session.user.username}/shows`}
|
||||
className="flex items-center space-x-3 rounded-md p-2"
|
||||
>
|
||||
<BsPersonVcard className="h-5 w-5 fill-current " />
|
||||
@@ -69,7 +73,7 @@ const DashboardSidebar = ({ session }: DashboardSidebarProps) => {
|
||||
<li className="">
|
||||
<Link
|
||||
rel="noopener noreferrer"
|
||||
href="dashboard/mixes"
|
||||
href={`${session.user.username}/mixes`}
|
||||
className="flex items-center space-x-3 rounded-md p-2"
|
||||
>
|
||||
<BsPersonBoundingBox className="h-5 w-5 fill-current " />
|
||||
|
||||
@@ -4,8 +4,8 @@ type UserModel = {
|
||||
name: string | null;
|
||||
email: string;
|
||||
bio: string | null;
|
||||
profileImage: string | null;
|
||||
headerImage: string | null;
|
||||
profileImage: string;
|
||||
headerImage: string;
|
||||
urls: string[] | null;
|
||||
};
|
||||
export default UserModel;
|
||||
|
||||
@@ -12,8 +12,12 @@ const mapAuthUserToUserModel = (
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
bio: user.bio,
|
||||
profileImage: user.profileImage,
|
||||
headerImage: user.headerImage,
|
||||
profileImage: user.profileImage
|
||||
? `https://mixyboos.twic.pics/${user.profileImage}?twic=v1/resize=256`
|
||||
: "/img/default-avatar.png",
|
||||
headerImage: user.headerImage
|
||||
? `https://mixyboos.twic.pics/${user.headerImage}?twic=v1/resize=1200x400`
|
||||
: "/img/default-header.png",
|
||||
urls: [],
|
||||
}
|
||||
: undefined;
|
||||
@@ -21,7 +25,7 @@ const mapAuthUserToUserModel = (
|
||||
const mapDbAuthUserToUserModel = (user: DbUser): UserModel => ({
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
name: user.name,
|
||||
name: user.name || user.username,
|
||||
email: user.email,
|
||||
bio: user.bio,
|
||||
profileImage: user.profileImage
|
||||
|
||||
Reference in New Issue
Block a user