Skip to content

Commit

Permalink
Formation share ID (#63)
Browse files Browse the repository at this point in the history
* setup new field

* actually save the share id from the form

* add copy formation share id button

* better button placement and copy

* PR feedback
  • Loading branch information
KMontag42 authored Dec 26, 2024
1 parent bd807b6 commit f56e8ff
Show file tree
Hide file tree
Showing 9 changed files with 249 additions and 9 deletions.
1 change: 1 addition & 0 deletions components/Builder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ export default function Builder({ data, formation: _formation }: Props) {
name={_formation?.name}
id={_formation?.id}
tags={tags}
formationShareId={_formation?.formationShareId}
/>
)}
<Button onClick={onDownloadButtonClick} className="h-8 px-2">
Expand Down
23 changes: 23 additions & 0 deletions components/CopyFormationShareId.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"use client";

import { Button } from "@/components/ui/button";
import { Copy } from "lucide-react";
import { toast } from "sonner";

export default function CopyFormationShareId({
formationShareId,
}: {
formationShareId: string;
}) {
return (
<Button
onClick={() => {
navigator.clipboard.writeText(formationShareId);
toast.success("Formation share ID copied to clipboard!");
}}
>
<Copy />
&nbsp;Copy import ID
</Button>
);
}
27 changes: 21 additions & 6 deletions components/FormationCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import LikeFormationButton from "@/components/LikeFormationButton";
import DeleteFormationButton from "@/components/DeleteFormationButton";
import ShareFormationButton from "@/components/ShareFormationButton";
import { Edit2 } from "lucide-react";
import CopyFormationShareId from "@/components/CopyFormationShareId";

type FormationCardProps = {
data: FormationData;
Expand All @@ -42,8 +43,17 @@ export default function FormationCard({
isLink,
currentUserId,
}: FormationCardProps) {
const { id, formation, artifact, username, user_image, name, votes, tags } =
data;
const {
id,
formation,
artifact,
username,
user_image,
name,
votes,
tags,
formationShareId,
} = data;

const layout = Math.trunc(data.layout);

Expand All @@ -59,11 +69,16 @@ export default function FormationCard({
<>
<CardHeader>
<CardTitle>
<div className="flex flex-col">
<p>{name}</p>
<div>
{tags && tags.map((tag) => <Badge key={tag}>{tag}</Badge>)}
<div className="flex flex-row justify-between">
<div className="flex flex-col">
<p>{name}</p>
<div>
{tags && tags.map((tag) => <Badge key={tag}>{tag}</Badge>)}
</div>
</div>
{formationShareId && (
<CopyFormationShareId formationShareId={formationShareId} />
)}
</div>
</CardTitle>
</CardHeader>
Expand Down
25 changes: 23 additions & 2 deletions components/SaveButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type SaveButtonProps = {
name?: string;
id?: number;
tags?: string[];
formationShareId?: string;
};

export default function SaveButton({
Expand All @@ -40,17 +41,21 @@ export default function SaveButton({
name,
id,
tags,
formationShareId,
}: SaveButtonProps) {
const [open, setOpen] = useState(false);
const router = useRouter();

const handleSave = async (e: FormEvent) => {
e.preventDefault();

const { name } = e.target as typeof e.target & {
const { name, formationShareId } = e.target as typeof e.target & {
name: { value: string };
formationShareId: { value: string };
};

console.log("formationShareId", formationShareId);

if (formation.filter((x) => x != "").length === 0) {
toast.error("Formation is empty!");
setOpen(false);
Expand All @@ -69,6 +74,7 @@ export default function SaveButton({
user_id: user.id,
name: name.value,
tags,
formationShareId: formationShareId.value,
};

const requestUrl = id ? `/api/formations/${id}` : "/api/formations";
Expand All @@ -85,6 +91,7 @@ export default function SaveButton({
formation: formation.join(","),
id: id || -1,
tags: JSON.stringify(formationData.tags),
formationShareId: formationData.formationShareId || "",
};

try {
Expand Down Expand Up @@ -120,6 +127,7 @@ export default function SaveButton({
className="px-4"
onSubmit={handleSave}
name={name}
formationShareId={formationShareId}
/>
<DrawerFooter className="pt-2">
<DrawerClose asChild>
Expand All @@ -136,7 +144,8 @@ function SaveFormationForm({
className,
onSubmit,
name,
}: React.ComponentProps<"form">) {
formationShareId,
}: React.ComponentProps<"form"> & { formationShareId?: string }) {
return (
<form
className={cn("grid items-center gap-4", className)}
Expand All @@ -147,11 +156,23 @@ function SaveFormationForm({
<Input
type="text"
id="name"
name="name"
placeholder="f2p Team"
defaultValue={name}
required
/>
</div>

<div className="grid gap-2">
<Label htmlFor="formationShareId">Formation Share ID</Label>
<Input
type="text"
id="formationShareId"
name="formationShareId"
placeholder="1a2a3a"
defaultValue={formationShareId}
/>
</div>
<Button type="submit">Save formation</Button>
</form>
);
Expand Down
1 change: 1 addition & 0 deletions drizzle/migrations/0003_red_nebula.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE `formations` ADD `formationShareId` text(255) DEFAULT '';
165 changes: 165 additions & 0 deletions drizzle/migrations/meta/0003_snapshot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
{
"version": "6",
"dialect": "sqlite",
"id": "e7282cd4-6540-40c3-a421-4ad5d75bc115",
"prevId": "d46d90ae-6248-41cc-99cf-5270c94282af",
"tables": {
"formations": {
"name": "formations",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": true
},
"formation": {
"name": "formation",
"type": "text(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"artifact": {
"name": "artifact",
"type": "text(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"layout": {
"name": "layout",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"user_id": {
"name": "user_id",
"type": "text(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "text(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"tags": {
"name": "tags",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'[]'"
},
"formationShareId": {
"name": "formationShareId",
"type": "text(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"roster": {
"name": "roster",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": true
},
"last_update": {
"name": "last_update",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"user_id": {
"name": "user_id",
"type": "text(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {
"roster_user_id_unique": {
"name": "roster_user_id_unique",
"columns": ["user_id"],
"isUnique": true
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"votes": {
"name": "votes",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": true
},
"formation_id": {
"name": "formation_id",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"user_id": {
"name": "user_id",
"type": "text(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {
"votes_formation_id_user_id_unique": {
"name": "votes_formation_id_user_id_unique",
"columns": ["formation_id", "user_id"],
"isUnique": true
}
},
"foreignKeys": {
"votes_formation_id_formations_id_fk": {
"name": "votes_formation_id_formations_id_fk",
"tableFrom": "votes",
"tableTo": "formations",
"columnsFrom": ["formation_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
}
},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"indexes": {}
}
}
7 changes: 7 additions & 0 deletions drizzle/migrations/meta/_journal.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
"when": 1730151629218,
"tag": "0002_medical_puck",
"breakpoints": true
},
{
"idx": 3,
"version": "6",
"when": 1735074547469,
"tag": "0003_red_nebula",
"breakpoints": true
}
]
}
3 changes: 3 additions & 0 deletions drizzle/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export const formations = sqliteTable("formations", {
userId: text("user_id", { length: 255 }).notNull(),
name: text("name", { length: 255 }).notNull(),
tags: text("tags", { mode: "json" }).$type<string[]>().default([]).notNull(),
formationShareId: text("formationShareId", { length: 255 })
.default("")
.notNull(),
});

export const votes = sqliteTable(
Expand Down
Loading

0 comments on commit f56e8ff

Please sign in to comment.