Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setlist and songUpdates #14

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions app/components/forms/song/SongForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,26 @@ const SongForm = forwardRef<
</div>
))}
</div>
<label>
<h2>Additional Information</h2>
<label>
Runtime in seconds
<Input
name="runtime"
defaultValue={song.runtime}
type="number"
title="RunTime (seconds)"
aria-label="RunTime in seconds"
className="text-xl w-full bg-inherit py-1 outline-none hover:cursor-text resize-none"
/>
</label>
<Textarea
name="notes"
placeholder="Notes"
defaultValue={song.notes}
className="text-xl w-full bg-inherit py-1 outline-none hover:cursor-text resize-none"
/>
</label>
{/* <button
type="submit"
className="bg-stone-200 px-5 py-2 rounded-md text-stone-800 mt-4"
Expand Down
15 changes: 14 additions & 1 deletion app/db/setlist.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,21 @@ export async function getSetlists() {
});
}

export async function getSetlistsByUserId(userId: number) {
return await prisma.setlist.findMany({
where: { authorId: userId },
include: {
songs: {
select: {
id: true,
},
},
},
});
}

export async function createSetlist(
data?: Pick<Setlist, "name" | "description">
data?: Pick<Setlist, "name" | "description" | "authorId">
) {
return await prisma.setlist.create({
data: { ...data },
Expand Down
11 changes: 8 additions & 3 deletions app/db/song.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ export async function getSong({ id }: Pick<Song, "id">) {
});
}

export async function getSongs() {
return await prisma.song.findMany();
/**
* Gets the songs of the currently logged in user
* @param userId
* @returns
*/
export async function getUserSongs(userId: number) {
return await prisma.song.findMany({ where: { authorId: userId } });
}

export async function createSong({ authorId }: Pick<Song, "authorId">) {
Expand All @@ -44,7 +49,7 @@ export async function updateSong({
data,
}: {
id: Song["id"];
data: Pick<Song, "title" | "attribution" | "stanzas">;
data: Pick<Song, "title" | "attribution" | "stanzas" | "runtime" | "notes">;
}) {
return await prisma.song.update({ where: { id: +id }, data });
}
31 changes: 31 additions & 0 deletions app/helpers/formatTime.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import formatTime from "./formatTime";

describe("Time ago tests", () => {
test("less than 1m ago", () => {
expect(
formatTime({
time: new Date() - 1,
})
).toStrictEqual("a few seconds ago");
});
});

describe("additional format testing", () => {
test("full date", () => {
expect(
formatTime({
time: "2020-04-06T18:19:00.000Z",
fullDate: true,
})
).toStrictEqual("April 6, 2020");
});
test("full date and time", () => {
expect(
formatTime({
time: "2020-04-06T18:19:00.000Z",
fullDate: true,
withTime: true,
})
).toStrictEqual("April 6, 2020 2:19 PM");
});
});
36 changes: 36 additions & 0 deletions app/helpers/formatTime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import moment from "moment";
Copy link
Contributor

Choose a reason for hiding this comment

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

Moment doesn't recommend using Moment anymore so maybe we should look at other libraries that are smaller (or just use native JS dates). What are we trying to display, just a string that says like "3m" or "4m". I can't imagine Grayson and I ever really putting seconds since our estimations of time aren't that exact.

Copy link
Contributor

Choose a reason for hiding this comment

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


/**
* Implements Moment.js for formatting dates
* https://momentjs.com/docs/#/displaying/fromnow/
*
* @param {{time:Date}} param0 input parameters
*/
const formatTime = ({
time = "",
fullDate = false,
withTime = false,
ago = true,
}) => {
if (fullDate) {
let format = "LL";
if (withTime) {
format += "L";
}
return moment(time).format(format);
}
return moment(time).fromNow(!ago);
};

export default formatTime;

/**
* formats the runtime in seconds to US-EN format.
*/
export const formatRunTime = (runtime: number) => {
if (runtime < 60) return `${runtime} sec.`;
let min = runtime / 60;
min = ~~min;
const remSec = runtime % 60;
return `${min} min. ${remSec} sec.`;
};
10 changes: 7 additions & 3 deletions app/routes/__app/setlists/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import type { Setlist } from "@prisma/client";
import { Link } from "@remix-run/react";
import type { LoaderArgs } from "@remix-run/node";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { Button } from "~/components/Button";
import { Search } from "~/components/Search";
import { getSetlists } from "~/db/setlist.db";
import { useSearch } from "~/lib/useSearch";
import { requireAuthentication } from "~/utils/auth.server";
import { getSetlistsByUserId } from "~/db/setlist.db";

export async function loader() {
const setlists = await getSetlists();
export async function loader({ request }: LoaderArgs) {
const user = await requireAuthentication(request);

const setlists = await getSetlistsByUserId(user.id);
return typedjson({
setlists,
});
Expand Down
4 changes: 4 additions & 0 deletions app/routes/__app/setlists/new.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ import { redirect } from "@remix-run/node";
import { typedjson } from "remix-typedjson";
import { createSetlist, setQRCode } from "~/db/setlist.db";
import { formDataToJson } from "~/helpers/formDataToJson";
import { currentAuthedUser } from "~/utils/auth.server";

export async function action({ request }: ActionArgs) {
const user = await currentAuthedUser(request);
if (!user) return redirect("/");
const formData = formDataToJson(await request.formData());
if (!formData.name) return;

try {
const setlist = await createSetlist({
name: formData.name as string,
description: formData?.description as string,
authorId: user.id as number,
});
await setQRCode(setlist, request);
return redirect(`/setlists`);
Expand Down
7 changes: 3 additions & 4 deletions app/routes/__app/songs/$id/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,17 @@ export async function action({ request }: ActionArgs) {
const formDataAsJson = formDataToJson(
await request.formData()
) as unknown as ISong;
const id = formDataAsJson.id;
const title = formDataAsJson.title;
const attribution = formDataAsJson.attribution;
const { notes, runtime, title, attribution, id } = formDataAsJson;
const stanzas = JSON.stringify(formDataAsJson.stanzas);

try {
const updatedSong = await updateSong({
id,
data: {
title,
attribution,
stanzas,
notes,
runtime: +runtime,
},
});
return typedjson({ ...updatedSong });
Expand Down
18 changes: 17 additions & 1 deletion app/routes/__app/songs/$id/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { Button } from "~/components/Button";
import { Stanza } from "~/components/Stanza";
import { getSong } from "~/db/song.db";
import { formatRunTime } from "~/helpers/formatTime";

export async function loader({ params }: LoaderArgs) {
if (!params.id) throw new Response("Not Found", { status: 404 });
Expand All @@ -19,7 +20,7 @@ export async function loader({ params }: LoaderArgs) {

export default function () {
const { song } = useTypedLoaderData<typeof loader>();
console.log(song.stanzas);

return (
<div className="max-w-xl mx-auto space-y-2">
<div className="flex items-center">
Expand Down Expand Up @@ -87,12 +88,27 @@ export default function () {
<p className="text-xl w-full bg-inherit py-1 outline-none hover:cursor-text resize-none text-stone-500">
{song.attribution}
</p>
<p className="text-xl w-full bg-inherit py-1 outline-none hover:cursor-text resize-none text-stone-500">
Run Time: {formatRunTime(song.runtime)}
</p>
</div>
<div className="space-y-7">
{song.stanzas.map((stanza) => (
<Stanza stanza={stanza} key={stanza.id} />
))}
</div>
<div>
<h2>Notes</h2>
<p className="text-xl w-full bg-inherit py-1 outline-none hover:cursor-text resize-none text-stone-500">
{song.notes}
</p>
{/* <h2>Public domain status</h2>
<p className="text-xl w-full bg-inherit py-1 outline-none hover:cursor-text resize-none text-stone-500">
{song.claimedPublicDomain
? "This song is considered in the public domain"
: "This song is not part of the public domain. Contact the writer, label, composer for use rights."}
</p> */}
</div>
</div>
</div>
</div>
Expand Down
5 changes: 2 additions & 3 deletions app/routes/__app/songs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import { Form, Link } from "@remix-run/react";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { Button } from "~/components/Button";
import { Search } from "~/components/Search";
import { getSongs } from "~/db/song.db";
import { getUserSongs } from "~/db/song.db";
import { useSearch } from "~/lib/useSearch";
import { requireAuthentication } from "~/utils/auth.server";

export async function loader({ request }: LoaderArgs) {
const user = await requireAuthentication(request);
console.log(user);
return typedjson({ songs: await getSongs() });
return typedjson({ songs: await getUserSongs(user.id) });
}

export default function SongsIndex() {
Expand Down
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"db:deploy": "npx prisma migrate deploy",
"db:push": "npx prisma db push",
"db:reset": "rm -r prisma/data.db && npm run db:push",
"db:hard-refresh": "rm -r prisma/data.db && npm run db:push && npm run db:seed",
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm down to just add the seed command to db:reset if you want?

"db:seed": "npx prisma db seed",
"db:studio": "npx prisma studio -p 7777 --browser none",
"dev": "concurrently \"npm run dev:css\" \"remix dev\"",
Expand Down Expand Up @@ -40,6 +41,7 @@
"debounce": "^1.2.1",
"dotenv-cli": "^6.0.0",
"fuse.js": "^6.6.2",
"moment": "^2.28.0",
"qrcode": "^1.5.1",
"qs": "^6.11.0",
"react": "^18.2.0",
Expand Down
Loading