Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusab committed Oct 15, 2024
1 parent 35e06b0 commit b1a3ac0
Show file tree
Hide file tree
Showing 22 changed files with 1,932 additions and 1,678 deletions.
28 changes: 14 additions & 14 deletions apps/dashboard/src/actions/invoice/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ export const deleteInvoiceSchema = z.object({
});

export const updateInvoiceSettingsSchema = z.object({
customerLabel: z.string().optional(),
fromLabel: z.string().optional(),
invoiceNoLabel: z.string().optional(),
issueDateLabel: z.string().optional(),
dueDateLabel: z.string().optional(),
descriptionLabel: z.string().optional(),
priceLabel: z.string().optional(),
quantityLabel: z.string().optional(),
totalLabel: z.string().optional(),
vatLabel: z.string().optional(),
taxLabel: z.string().optional(),
paymentDetailsLabel: z.string().optional(),
noteLabel: z.string().optional(),
logoUrl: z.string().optional(),
customer_label: z.string().optional(),
from_label: z.string().optional(),
invoice_no_label: z.string().optional(),
issue_date_label: z.string().optional(),
due_date_label: z.string().optional(),
description_label: z.string().optional(),
price_label: z.string().optional(),
quantity_label: z.string().optional(),
total_label: z.string().optional(),
vat_label: z.string().optional(),
tax_label: z.string().optional(),
payment_details_label: z.string().optional(),
note_label: z.string().optional(),
logo_url: z.string().optional(),
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use server";

import { authActionClient } from "@/actions/safe-action";
import { revalidateTag } from "next/cache";
import { updateInvoiceSettingsSchema } from "./schema";

export const updateInvoiceSettingsAction = authActionClient
Expand All @@ -12,17 +13,13 @@ export const updateInvoiceSettingsAction = authActionClient
const teamId = user.team_id;

const { data, error } = await supabase
.rpc("update_team_setting", {
team_id: teamId,
setting_key: "invoice",
setting_path: [setting],
new_value: setting,
create_missing: true,
})
.select("*")
.from("invoice_templates")
.upsert({ team_id: teamId, ...setting }, { onConflict: "team_id" })
.eq("team_id", teamId)
.select()
.single();

console.log(data, error);
revalidateTag(`invoice_templates_${teamId}`);

return data;
});
13 changes: 12 additions & 1 deletion apps/dashboard/src/components/invoice/customer-content.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"use client";

import { updateInvoiceSettingsAction } from "@/actions/invoice/update-invoice-settings-action";
import { Editor } from "@/components/editor";
import { useAction } from "next-safe-action/hooks";
import type { JSONContent } from "novel";
import { Controller, useFormContext } from "react-hook-form";
import { LabelInput } from "./label-input";
Expand All @@ -25,9 +27,18 @@ const defaultContent: JSONContent = {
export function CustomerContent() {
const { control } = useFormContext();

const updateInvoiceSettings = useAction(updateInvoiceSettingsAction);

return (
<div>
<LabelInput name="settings.customerLabel" />
<LabelInput
name="settings.customer_label"
onSave={(value) => {
updateInvoiceSettings.execute({
customer_label: value,
});
}}
/>
<Controller
name="customerContent"
control={control}
Expand Down
13 changes: 12 additions & 1 deletion apps/dashboard/src/components/invoice/due-date.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { updateInvoiceSettingsAction } from "@/actions/invoice/update-invoice-settings-action";
import { Calendar } from "@midday/ui/calendar";
import { Popover, PopoverContent, PopoverTrigger } from "@midday/ui/popover";
import { format } from "date-fns";
import { useAction } from "next-safe-action/hooks";
import { useState } from "react";
import { useFormContext } from "react-hook-form";
import { LabelInput } from "./label-input";
Expand All @@ -11,6 +13,8 @@ export function DueDate() {
const dueDate = watch("dueDate");
const [isOpen, setIsOpen] = useState(false);

const updateInvoiceSettings = useAction(updateInvoiceSettingsAction);

const handleSelect = (date: Date | undefined) => {
if (date) {
setValue("dueDate", date, { shouldValidate: true });
Expand All @@ -21,7 +25,14 @@ export function DueDate() {
return (
<div className="flex space-x-1 items-center">
<div className="flex items-center">
<LabelInput name="settings.dueDateLabel" />
<LabelInput
name="settings.due_date_label"
onSave={(value) => {
updateInvoiceSettings.execute({
due_date_label: value,
});
}}
/>
<span className="text-[11px] text-[#878787] font-mono">:</span>
</div>
<Popover open={isOpen} onOpenChange={setIsOpen}>
Expand Down
42 changes: 26 additions & 16 deletions apps/dashboard/src/components/invoice/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,42 @@ import { Logo } from "./logo";
import { Meta } from "./meta";
import { NoteContent } from "./note-content";
import { PaymentDetails } from "./payment-details";
import { type InvoiceFormValues, invoiceSchema } from "./schema";
import {
type InvoiceFormValues,
type InvoiceSettings,
invoiceSchema,
} from "./schema";
import { Summary } from "./summary";

type Props = {
teamId: string;
settings: InvoiceSettings;
};

export function Form({ teamId }: Props) {
const defaultSettings: InvoiceSettings = {
customer_label: "To",
from_label: "From",
invoice_no_label: "Invoice No",
issue_date_label: "Issue Date",
due_date_label: "Due Date",
description_label: "Description",
price_label: "Price",
quantity_label: "Quantity",
total_label: "Total",
vat_label: "VAT",
tax_label: "Tax",
payment_details_label: "Payment Details",
note_label: "Note",
logo_url: undefined,
};

export function Form({ teamId, settings }: Props) {
const form = useForm<InvoiceFormValues>({
resolver: zodResolver(invoiceSchema),
defaultValues: {
settings: {
customerLabel: "To",
fromLabel: "From",
invoiceNoLabel: "Invoice No",
issueDateLabel: "Issue Date",
dueDateLabel: "Due Date",
descriptionLabel: "Description",
priceLabel: "Price",
quantityLabel: "Quantity",
totalLabel: "Total",
vatLabel: "VAT",
taxLabel: "Tax",
paymentDetailsLabel: "Payment Details",
noteLabel: "Note",
logoUrl: undefined,
...defaultSettings,
...settings,
},
invoiceNumber: "INV-0001",
currency: "USD",
Expand Down
13 changes: 12 additions & 1 deletion apps/dashboard/src/components/invoice/from-content.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"use client";

import { updateInvoiceSettingsAction } from "@/actions/invoice/update-invoice-settings-action";
import { Editor } from "@/components/editor";
import { useAction } from "next-safe-action/hooks";
import type { JSONContent } from "novel";
import { Controller, useFormContext } from "react-hook-form";
import { LabelInput } from "./label-input";
Expand Down Expand Up @@ -53,9 +55,18 @@ const defaultContent: JSONContent = {
export function FromContent() {
const { control } = useFormContext();

const updateInvoiceSettings = useAction(updateInvoiceSettingsAction);

return (
<div>
<LabelInput name="settings.fromLabel" />
<LabelInput
name="settings.from_label"
onSave={(value) => {
updateInvoiceSettings.execute({
from_label: value,
});
}}
/>
<Controller
name="fromContent"
control={control}
Expand Down
4 changes: 2 additions & 2 deletions apps/dashboard/src/components/invoice/invoice-no.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ export function InvoiceNo() {
<div className="flex space-x-1 items-center">
<div className="flex items-center">
<LabelInput
name="settings.invoiceNoLabel"
name="settings.invoice_no_label"
onSave={(value) => {
updateInvoiceSettings.execute({
invoiceNoLabel: value,
invoice_no_label: value,
});
}}
/>
Expand Down
4 changes: 2 additions & 2 deletions apps/dashboard/src/components/invoice/issue-date.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ export function IssueDate() {
<div className="flex space-x-1 items-center">
<div className="flex items-center">
<LabelInput
name="settings.issueDateLabel"
name="settings.issue_date_label"
onSave={(value) => {
updateInvoiceSettings.execute({
invoiceNoLabel: value,
issue_date_label: value,
});
}}
/>
Expand Down
44 changes: 40 additions & 4 deletions apps/dashboard/src/components/invoice/line-items.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"use client";

import { updateInvoiceSettingsAction } from "@/actions/invoice/update-invoice-settings-action";
import { Button } from "@midday/ui/button";
import { Icons } from "@midday/ui/icons";
import { Label } from "@midday/ui/label";
import { Reorder, useDragControls, useMotionValue } from "framer-motion";
import { useAction } from "next-safe-action/hooks";
import { useFieldArray, useFormContext } from "react-hook-form";
import { AmountInput } from "./amount-input";
import { Input } from "./input";
Expand All @@ -18,6 +20,8 @@ export function LineItems() {
name: "lineItems",
});

const updateInvoiceSettings = useAction(updateInvoiceSettingsAction);

const reorderList = (newFields: typeof fields) => {
const firstDiffIndex = fields.findIndex(
(field, index) => field.id !== newFields[index]?.id,
Expand All @@ -42,10 +46,42 @@ export function LineItems() {
return (
<div className="space-y-4">
<div className="flex items-end mb-2">
<LabelInput name="settings.descriptionLabel" className="w-1/2 mr-4" />
<LabelInput name="settings.priceLabel" className="w-40 mr-4" />
<LabelInput name="settings.quantityLabel" className="w-24 mr-4" />
<LabelInput name="settings.vatLabel" className="w-24 text-right" />
<LabelInput
name="settings.description_label"
onSave={(value) => {
updateInvoiceSettings.execute({
description_label: value,
});
}}
className="w-1/2 mr-4"
/>
<LabelInput
name="settings.price_label"
onSave={(value) => {
updateInvoiceSettings.execute({
price_label: value,
});
}}
className="w-40 mr-4"
/>
<LabelInput
name="settings.quantity_label"
onSave={(value) => {
updateInvoiceSettings.execute({
quantity_label: value,
});
}}
className="w-24 mr-4"
/>
<LabelInput
name="settings.vat_label"
onSave={(value) => {
updateInvoiceSettings.execute({
vat_label: value,
});
}}
className="w-24 text-right"
/>
</div>

<Reorder.Group
Expand Down
12 changes: 10 additions & 2 deletions apps/dashboard/src/components/invoice/logo.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
"use client";

import { updateInvoiceSettingsAction } from "@/actions/invoice/update-invoice-settings-action";
import { useUpload } from "@/hooks/use-upload";
import { Skeleton } from "@midday/ui/skeleton";
import { useToast } from "@midday/ui/use-toast";
import { useAction } from "next-safe-action/hooks";
import { useFormContext } from "react-hook-form";
import type { InvoiceFormValues } from "./schema";

export function Logo({ teamId }: { teamId: string }) {
const { watch, setValue } = useFormContext<InvoiceFormValues>();
const logoUrl = watch("logoUrl");
const logoUrl = watch("settings.logo_url");
const { uploadFile, isLoading } = useUpload();
const { toast } = useToast();

const updateInvoiceSettings = useAction(updateInvoiceSettingsAction);

const handleUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file) {
Expand All @@ -22,7 +26,11 @@ export function Logo({ teamId }: { teamId: string }) {
bucket: "avatars",
});

setValue("logoUrl", url, { shouldValidate: true });
setValue("settings.logo_url", url, { shouldValidate: true });

updateInvoiceSettings.execute({
logo_url: url,
});
} catch (error) {
toast({
title: "Something went wrong, please try again.",
Expand Down
14 changes: 13 additions & 1 deletion apps/dashboard/src/components/invoice/note-content.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
"use client";

import { updateInvoiceSettingsAction } from "@/actions/invoice/update-invoice-settings-action";
import { Editor } from "@/components/editor";
import { useAction } from "next-safe-action/hooks";
import { LabelInput } from "./label-input";

export function NoteContent() {
const updateInvoiceSettings = useAction(updateInvoiceSettingsAction);

return (
<div>
<LabelInput name="settings.noteLabel" className="mb-2 block" />
<LabelInput
name="settings.note_label"
onSave={(value) => {
updateInvoiceSettings.execute({
note_label: value,
});
}}
className="mb-2 block"
/>
<Editor className="h-[78px]" />
</div>
);
Expand Down
14 changes: 13 additions & 1 deletion apps/dashboard/src/components/invoice/payment-details.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
"use client";

import { updateInvoiceSettingsAction } from "@/actions/invoice/update-invoice-settings-action";
import { Editor } from "@/components/editor";
import { useAction } from "next-safe-action/hooks";
import { LabelInput } from "./label-input";

export function PaymentDetails() {
const updateInvoiceSettings = useAction(updateInvoiceSettingsAction);

return (
<div>
<LabelInput name="settings.paymentDetailsLabel" className="mb-2 block" />
<LabelInput
name="settings.payment_details_label"
onSave={(value) => {
updateInvoiceSettings.execute({
payment_details_label: value,
});
}}
className="mb-2 block"
/>
<Editor className="h-[78px]" />
</div>
);
Expand Down
Loading

0 comments on commit b1a3ac0

Please sign in to comment.