diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..a8baea7 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,60 @@ +name: 'Publish' +on: workflow_dispatch + +env: + CARGO_INCREMENTAL: 0 + RUST_BACKTRACE: short + RUSTFLAGS: '-W unreachable-pub -W rust-2021-compatibility' + +jobs: + publish-tauri: + strategy: + fail-fast: false + matrix: + settings: + - platform: 'macos-latest' + args: '--target universal-apple-darwin' + - platform: 'ubuntu-22.04' + args: '' + - platform: 'windows-latest' + args: '--target x86_64-pc-windows-msvc' + runs-on: ${{ matrix.settings.platform }} + steps: + - uses: actions/checkout@v3 + - name: setup node + uses: actions/setup-node@v3 + with: + node-version: 20 + - uses: dtolnay/rust-toolchain@stable + with: + targets: aarch64-apple-darwin + - name: install dependencies (ubuntu only) + if: matrix.settings.platform == 'ubuntu-22.04' + run: | + sudo apt-get update + sudo apt-get install -y build-essential libssl-dev javascriptcoregtk-4.1 libayatana-appindicator3-dev libsoup-3.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev webkit2gtk-4.1 librsvg2-dev patchelf + - name: Install bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: latest + - name: Setup node and cache for package data + uses: actions/setup-node@v3 + with: + node-version: 'lts/*' + cache: 'bun' + cache-dependency-path: bun.lockb + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + - run: bun install + - uses: tauri-apps/tauri-action@dev + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tagName: v__VERSION__ + releaseName: 'v__VERSION__' + releaseBody: 'See the assets to download this version and install.' + releaseDraft: true + prerelease: false + args: ${{ matrix.settings.args }} + includeDebug: false \ No newline at end of file diff --git a/src/bindings.ts b/src/bindings.ts index 1e0205e..50260a0 100644 --- a/src/bindings.ts +++ b/src/bindings.ts @@ -16,10 +16,21 @@ export type GetInvoiceData = { status: string; }; +export type GetClientData = { + id: number; + name: string; + email: string; + phoneNumber: string; +}; + export function getInvoices(indicies: Indicies) { return invoke("get_invoices", { companyId: StateService().state.companyId, indicies }); } +export function getClients(indicies: Indicies) { + return invoke("get_clients", { companyId: StateService().state.companyId, indicies }); +} + export function getCompany(id: number | null) { return invoke("get_company", { id }); } @@ -31,6 +42,7 @@ export function createCompany(data: CreateCompanyData) { export function migrateAndPopulate() { return invoke("migrate_and_populate"); } + export async function getCompanies(exclude?: number) { return await invoke("get_companies", { exclude }); } diff --git a/src/screens/Dashboard/components/Box.tsx b/src/screens/Dashboard/components/Box.tsx index 6a63506..6281f22 100644 --- a/src/screens/Dashboard/components/Box.tsx +++ b/src/screens/Dashboard/components/Box.tsx @@ -2,9 +2,7 @@ import type { ParentComponent } from "solid-js"; const Box: ParentComponent<{ class: string }> = (props) => { return ( -
- {props.children} -
+
{props.children}
); }; diff --git a/src/screens/Dashboard/components/Form/Dropdown.tsx b/src/screens/Dashboard/components/Form/Dropdown.tsx index e69de29..165eb97 100644 --- a/src/screens/Dashboard/components/Form/Dropdown.tsx +++ b/src/screens/Dashboard/components/Form/Dropdown.tsx @@ -0,0 +1,95 @@ +import type { Component, JSX } from "solid-js"; +import { For, createSignal } from "solid-js"; +import { DisclosureStateChild, Listbox, ListboxButton, ListboxOption, ListboxOptions, Transition } from "terracotta"; +import { TbSelector } from "solid-icons/tb"; +import { FiCheck } from "solid-icons/fi"; + +interface DropdownItem { + id: number; + name: string; +} + +interface DropdownProps { + data: DropdownItem[]; + onSelect: (value: DropdownItem) => void; +} + +const Dropdown: Component = (props) => { + const [selected, setSelected] = createSignal(props.data[0]); + + const handleSelect = (value: DropdownItem | undefined) => { + if (!value) return; + setSelected(value); + props.onSelect(value); + }; + + return ( +
+ +
+ + {selected().name} + + + + + {({ isOpen }): JSX.Element => ( + + + + {(item): JSX.Element => ( + + {({ isActive, isSelected }): JSX.Element => ( +
+ + {item.name} + + {isSelected() ? ( + + + + ) : null} +
+ )} +
+ )} +
+
+
+ )} +
+
+
+
+ ); +}; + +export default Dropdown; diff --git a/src/screens/Dashboard/components/Form/Input.tsx b/src/screens/Dashboard/components/Form/Input.tsx index e69de29..f4c9fd8 100644 --- a/src/screens/Dashboard/components/Form/Input.tsx +++ b/src/screens/Dashboard/components/Form/Input.tsx @@ -0,0 +1,40 @@ +import type { Component } from "solid-js"; + +type TextInputProps = { + type: "text" | "date"; + onChange: (value: string) => void; + label: string; + defaultValue?: string; +}; + +type NumberInputProps = { + type: "number"; + onChange: (value: number) => void; + label: string; + defaultValue?: number; +}; + +type InputProps = TextInputProps | NumberInputProps; + +const Input: Component = (props) => { + const handleInput = (e: Event) => { + const value = (e.target as HTMLInputElement).value; + if (props.type === "number") { + props.onChange(Number(value) as never); + } else { + props.onChange(value as never); + } + }; + + return ( + + ); +}; + +export default Input; diff --git a/src/screens/Dashboard/components/Form/Table.tsx b/src/screens/Dashboard/components/Form/Table.tsx index e69de29..35edd76 100644 --- a/src/screens/Dashboard/components/Form/Table.tsx +++ b/src/screens/Dashboard/components/Form/Table.tsx @@ -0,0 +1,7 @@ +import type { Component } from "solid-js"; + +const Table: Component<{}> = (props) => { + return
; +}; + +export default Table; diff --git a/src/screens/Dashboard/components/StatBox.tsx b/src/screens/Dashboard/components/StatBox.tsx index 1488351..3ae58b5 100644 --- a/src/screens/Dashboard/components/StatBox.tsx +++ b/src/screens/Dashboard/components/StatBox.tsx @@ -12,7 +12,7 @@ const StatBox: Component<{ }; return ( -
+
diff --git a/src/screens/Dashboard/pages/Sales/Clients/ClientDetail.tsx b/src/screens/Dashboard/pages/Sales/Clients/ClientDetail.tsx index 91bdacf..d199d4c 100644 --- a/src/screens/Dashboard/pages/Sales/Clients/ClientDetail.tsx +++ b/src/screens/Dashboard/pages/Sales/Clients/ClientDetail.tsx @@ -4,6 +4,7 @@ import Container from "@/screens/Dashboard/components/Container"; import PageHeader from "@/screens/Dashboard/components/PageHeader"; import HeaderButton from "@/screens/Dashboard/components/PageHeader/HeaderButton"; import StatBox from "@/screens/Dashboard/components/StatBox"; +import Table from "@/screens/Dashboard/components/Table"; import { useNavigate, useParams } from "@solidjs/router"; import type { Component } from "solid-js"; @@ -28,7 +29,16 @@ const ClientDetail: Component = () => {
-
+
+ {}} + /> + ddd diff --git a/src/screens/Dashboard/pages/Sales/Clients/ManageClient.tsx b/src/screens/Dashboard/pages/Sales/Clients/ManageClient.tsx index 5d8a74c..05d1a3b 100644 --- a/src/screens/Dashboard/pages/Sales/Clients/ManageClient.tsx +++ b/src/screens/Dashboard/pages/Sales/Clients/ManageClient.tsx @@ -1,12 +1,25 @@ +import { useI18n } from "@/i18n"; +import Container from "@/screens/Dashboard/components/Container"; +import PageHeader from "@/screens/Dashboard/components/PageHeader"; +import HeaderButton from "@/screens/Dashboard/components/PageHeader/HeaderButton"; import { useParams } from "@solidjs/router"; import type { Component } from "solid-js"; const ManageClient: Component = () => { const params = useParams<{ readonly id?: string }>(); + const [t] = useI18n(); + return ( -
-

Create Client

-
+ + {}} buttonType="primary"> + Save + , + ]} + /> + ); }; diff --git a/src/screens/Dashboard/pages/Sales/Clients/index.tsx b/src/screens/Dashboard/pages/Sales/Clients/index.tsx index 3685b4e..c96b480 100644 --- a/src/screens/Dashboard/pages/Sales/Clients/index.tsx +++ b/src/screens/Dashboard/pages/Sales/Clients/index.tsx @@ -1,50 +1,37 @@ -import { type Template, getTemplates } from "@/bindings"; +import { getClients } from "@/bindings"; import { useI18n } from "@/i18n"; import Table, { type Indicies } from "@/screens/Dashboard/components/Table"; -import { FiEdit, FiPlus, FiTrash } from "solid-icons/fi"; +import { FiEdit, FiPlus } from "solid-icons/fi"; import type { Component } from "solid-js"; import { useNavigate } from "@solidjs/router"; import PageHeader from "@/screens/Dashboard/components/PageHeader"; import HeaderButton from "@/screens/Dashboard/components/PageHeader/HeaderButton"; import Container from "@/screens/Dashboard/components/Container"; -import { Button } from "@/shared/components/Button"; const Clients: Component = () => { const [t] = useI18n(); const navigate = useNavigate(); const loadPage = async (indices: Indicies) => { - const data = await getTemplates(indices); - console.log(data); - return data; + return await getClients(indices); }; - const handleEdit = (item: Template) => { + const handleEdit = (item) => { navigate(`detail/${item.id}`); }; - const handleDelete = (item: Template) => { - console.log("Delete:", item); - // Handle delete action - }; - const rowActions = [ { label: "Edit", onClick: handleEdit, icon: FiEdit, }, - { - label: "Delete", - onClick: handleDelete, - icon: FiTrash, - }, ]; return ( navigate("new")} buttonType="primary"> @@ -55,7 +42,8 @@ const Clients: Component = () => { columns={[ { field: "id", header: "ID" }, { field: "name", header: "Name" }, - { field: "templateType", header: "Type" }, + { field: "email", header: "Email" }, + { field: "phoneNumber", header: "Phone" }, ]} totalItems={10} loadPage={loadPage} diff --git a/src/screens/Dashboard/pages/Sales/Invoices/ManageInvoice.tsx b/src/screens/Dashboard/pages/Sales/Invoices/ManageInvoice.tsx index 633c111..9c03a14 100644 --- a/src/screens/Dashboard/pages/Sales/Invoices/ManageInvoice.tsx +++ b/src/screens/Dashboard/pages/Sales/Invoices/ManageInvoice.tsx @@ -8,6 +8,8 @@ import { useParams } from "@solidjs/router"; import Form from "@/screens/Dashboard/components/Form"; import type { Invoice } from "@/bindings"; import Container from "@/screens/Dashboard/components/Container"; +import Input from "@/screens/Dashboard/components/Form/Input"; +import Dropdown from "@/screens/Dashboard/components/Form/Dropdown"; const ManageInvoice: Component = () => { const params = useParams<{ readonly id?: string }>(); @@ -54,33 +56,24 @@ const ManageInvoice: Component = () => {
{(field) => ( -
- -
+ field().handleChange(data)} + /> )}
{(field) => ( -
- -
+ field().handleChange(data.id)} + /> )}
diff --git a/src/styles/index.css b/src/styles/index.css index 79e1e6d..41fd1b2 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -41,6 +41,7 @@ input[type=number] { --color-secondary: #52525b; --bg-primary: #EAEAEB; --bg-secondary: #FFFFFF; + --bg-element: #E6E6E6; --color-lightgrey: #E5E7E7; --color-danger: #b91c1c; --color-warning: #f97316; @@ -61,6 +62,7 @@ input[type=number] { --color-secondary: #a1a1aa; --bg-primary: #262626; --bg-secondary: #636366; + --bg-element: #282828; --color-lightgrey: #E5E7E7; --color-danger: #f87171; --color-warning: #facc15; diff --git a/unocss.config.ts b/unocss.config.ts index 1ee88cb..0efb1dc 100644 --- a/unocss.config.ts +++ b/unocss.config.ts @@ -32,6 +32,7 @@ export default defineConfig({ }, backgroundColor: { primary: "var(--bg-primary)", + element: "var(--bg-element)", secondary: "var(--bg-secondary)", default: "var(--color-default)", fills: {