Skip to content

Commit

Permalink
Merge branch 'main' of github.com:maidh91/wealthfolio into refactor-c…
Browse files Browse the repository at this point in the history
…ommands-tauri
  • Loading branch information
maidh91 committed Sep 7, 2024
2 parents 026c571 + 91f23b2 commit 6d9f84b
Show file tree
Hide file tree
Showing 16 changed files with 76 additions and 80 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "wealthfolio-app",
"private": true,
"version": "1.0.6",
"version": "1.0.7",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/Cargo.lock

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

4 changes: 2 additions & 2 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "wealthfolio-app"
version = "1.0.6"
version = "1.0.7"
description = "Portfolio tracker"
authors = ["Aziz Fadil"]
license = "MIT"
license = "LGPL-3.0"
repository = ""
edition = "2021"

Expand Down
10 changes: 6 additions & 4 deletions src-tauri/src/asset/asset_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,13 +328,15 @@ impl AssetService {

for yahoo_quote in quotes_history {
let timestamp = yahoo_quote.timestamp as i64;
let naive_datetime = chrono::DateTime::from_timestamp(timestamp, 0)
.ok_or_else(|| format!("Invalid timestamp: {}", timestamp))?
.naive_utc();

let new_quote = Quote {
id: uuid::Uuid::new_v4().to_string(),
created_at: chrono::NaiveDateTime::from_timestamp_opt(timestamp, 0)
.ok_or_else(|| format!("Invalid timestamp: {}", timestamp))?,
created_at: naive_datetime,
data_source: "YAHOO".to_string(),
date: chrono::NaiveDateTime::from_timestamp_opt(timestamp, 0)
.ok_or_else(|| format!("Invalid date timestamp: {}", timestamp))?,
date: naive_datetime,
symbol: symbol.to_string(),
open: yahoo_quote.open,
high: yahoo_quote.high,
Expand Down
19 changes: 0 additions & 19 deletions src-tauri/src/models.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use chrono::NaiveDateTime;
use diesel::prelude::*;
use diesel::sql_types::{Double, Nullable, Text};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Queryable, Identifiable, AsChangeset, Serialize, Deserialize, Debug)]
Expand Down Expand Up @@ -327,24 +326,6 @@ pub struct Holding {
pub sectors: Option<Vec<Sector>>,
}

#[derive(QueryableByName, Debug)]
pub struct AggregatedHolding {
#[diesel(sql_type = Text)]
pub account_id: String,
#[diesel(sql_type = Text)]
pub account_name: String,
#[diesel(sql_type = Text)]
pub asset_id: String,
#[diesel(sql_type = Text)]
pub asset_name: String, // Assuming this is the field name for asset_symbol
#[diesel(sql_type = Nullable<Double>)]
pub quantity: Option<f64>,
#[diesel(sql_type = Double)]
pub book_value: f64,
#[diesel(sql_type = Nullable<Double>)]
pub average_cost: Option<f64>,
}

// FinancialSnapshot and FinancialHistory structs with serde for serialization/deserialization
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/src/portfolio/portfolio_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ impl PortfolioService {
cumulative_cash += activity_amount * activity.unit_price - activity_fee;
}
"WITHDRAWAL" | "TRANSFER_OUT" | "CONVERSION_OUT" => {
cumulative_cash -= activity_amount + activity_fee;
net_deposit -= activity_amount;
cumulative_cash -= activity_amount * activity.unit_price + activity_fee;
net_deposit -= activity_amount * activity.unit_price;
}
"FEE" | "TAX" => {
cumulative_cash -= activity_fee;
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"package": {
"productName": "Wealthfolio",
"version": "1.0.6"
"version": "1.0.7"
},
"tauri": {
"allowlist": {
Expand Down
4 changes: 2 additions & 2 deletions src/components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {
Goal,
Trash,
Ungroup,
Upload,
Import,
Users,
ListCollapse,
Wallet,
Expand Down Expand Up @@ -94,7 +94,7 @@ export const Icons = {
WalletCards: WalletCards,
StretchHorizontal: StretchHorizontal,
Menu: TableProperties,
Upload: Upload,
Import: Import,
FileText: FileText,
XCircle: XCircle,
ScrollText: ScrollText,
Expand Down
6 changes: 3 additions & 3 deletions src/lib/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ export const newGoalSchema = z.object({

export const newActivitySchema = z.object({
id: z.string().uuid().optional(),
accountId: z.string(),
accountId: z.string().min(1, { message: 'Account ID is required' }),
activityDate: z.date(),
currency: z.string(),
currency: z.string().min(1, { message: 'Currency is required' }),
fee: z.coerce
.number({
required_error: 'Please enter a valid fee.',
Expand All @@ -51,7 +51,7 @@ export const newActivitySchema = z.object({
invalid_type_error: 'Quantity must be a positive number.',
})
.min(0, { message: 'Quantity must be a positive number.' }),
assetId: z.string(),
assetId: z.string().min(1, { message: 'Asset ID is required' }),
activityType: z.enum([
'BUY',
'SELL',
Expand Down
16 changes: 9 additions & 7 deletions src/pages/activity/activity-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import ActivityTable from './components/activity-table';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Account, ActivityDetails } from '@/lib/types';
import { getAccounts } from '@/commands/account';
// import { getActivities } from '@/commands/activity';
import { ActivityDeleteModal } from './components/activity-delete-modal';
import { deleteActivity } from '@/commands/activity';
import { toast } from '@/components/ui/use-toast';
Expand Down Expand Up @@ -65,15 +64,15 @@ const ActivityPage = () => {
<div className="flex flex-col p-6">
<ApplicationHeader heading="Activity">
<div className="flex items-center space-x-2">
<Button variant="outline" size="icon" title="Import" asChild>
<Button size="sm" title="Import" asChild>
<Link to={'/import'}>
<Icons.Upload className="h-4 w-4" />
<span className="sr-only">Import</span>
<Icons.Import className="mr-2 h-4 w-4" />
Upload CSV
</Link>
</Button>
<Button size="sm" onClick={() => setShowEditModal(true)}>
<Button variant="outline" size="sm" onClick={() => setShowEditModal(true)}>
<Icons.PlusCircle className="mr-2 h-4 w-4" />
Add Activity
Add Manually
</Button>
</div>
</ApplicationHeader>
Expand All @@ -97,7 +96,10 @@ const ActivityPage = () => {
}
activity={selectedActivity}
open={showEditModal}
onClose={() => setShowEditModal(false)}
onClose={() => {
setShowEditModal(false);
setSelectedActivity(null);
}}
/>
<ActivityDeleteModal
isOpen={showDeleteAlert}
Expand Down
6 changes: 3 additions & 3 deletions src/pages/activity/components/activity-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ const AssetActivityFields = ({ defaultAssetId }: AssetActivityFieldsProps) => {
<FormItem>
<FormLabel>Shares</FormLabel>
<FormControl>
<Input type="number" inputMode="decimal" placeholder="Shares" {...field} />
<Input type="number" inputMode="decimal" min="0" placeholder="Shares" {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -382,7 +382,7 @@ const AssetActivityFields = ({ defaultAssetId }: AssetActivityFieldsProps) => {
<FormItem>
<FormLabel>Price</FormLabel>
<FormControl>
<Input type="number" inputMode="decimal" placeholder="Price" {...field} />
<Input type="number" inputMode="decimal" min="0" placeholder="Price" {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -395,7 +395,7 @@ const AssetActivityFields = ({ defaultAssetId }: AssetActivityFieldsProps) => {
<FormItem>
<FormLabel>Fee</FormLabel>
<FormControl>
<Input type="number" inputMode="decimal" placeholder="Fee" {...field} />
<Input type="number" inputMode="decimal" min="0" placeholder="Fee" {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand Down
11 changes: 7 additions & 4 deletions src/pages/activity/components/ticker-search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,13 @@ function TickerSearchInput({ selectedResult, defaultValue, onSelectResult }: Sea
const tickers = data?.sort((a, b) => b.score - a.score);

return (
<Command
shouldFilter={false}
className="h-auto w-full rounded-lg border border-b-0 shadow-none"
>
<Command
shouldFilter={false}
className={cn(
'h-auto w-full rounded-lg border shadow-none',
{ 'border-b-0': !isLoading && !isError && !(tickers && tickers.length > 0) }
)}
>
<CommandInput
value={searchQuery}
onValueChange={setSearchQuery}
Expand Down
37 changes: 23 additions & 14 deletions src/pages/activity/import/import-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
import { useState, useEffect } from 'react';
import { useForm } from 'react-hook-form';
import * as z from 'zod';
import { Link } from 'react-router-dom';

import { EmptyPlaceholder } from '@/components/empty-placeholder';

Expand Down Expand Up @@ -180,7 +181,7 @@ export const ActivityImportForm = ({ onSuccess, onError }: ActivityImportFormPro
</>
) : (
<>
<EmptyPlaceholder.Icon name="Upload" />
<EmptyPlaceholder.Icon name="Import" />
<EmptyPlaceholder.Title>
Drag and drop your CSV file here
</EmptyPlaceholder.Title>
Expand All @@ -196,19 +197,27 @@ export const ActivityImportForm = ({ onSuccess, onError }: ActivityImportFormPro
</FormItem>
)}
/>
<Button type="submit" disabled={isLoading}>
{isLoading ? (
<>
<Icons.Spinner className="mr-2 h-4 w-4 animate-spin" />
<span className="hidden sm:ml-2 sm:inline">Validating activities...</span>
</>
) : (
<>
<Icons.Upload className="mr-2 h-4 w-4" />
<span className="hidden sm:ml-2 sm:inline">Import activities</span>
</>
)}
</Button>
<div className="flex space-x-4">
<Button type="button" variant="outline" asChild>
<Link to="/activities">
{/* <Icons.ArrowLeft className="mr-2 h-4 w-4" /> */}
<span className="hidden sm:ml-2 sm:inline">Cancel</span>
</Link>
</Button>
<Button type="submit" disabled={isLoading}>
{isLoading ? (
<>
<Icons.Spinner className="mr-2 h-4 w-4 animate-spin" />
<span className="hidden sm:ml-2 sm:inline">Validating activities...</span>
</>
) : (
<>
<Icons.Import className="mr-2 h-4 w-4" />
<span className="hidden sm:ml-2 sm:inline">Import activities</span>
</>
)}
</Button>
</div>
</form>
</Form>
);
Expand Down
2 changes: 1 addition & 1 deletion src/pages/activity/import/import-validation-alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const ValidationAlert: React.FC<ValidationAlertProps> = ({
</>
) : (
<>
<Icons.Upload className="mr-2 h-4 w-4" />
<Icons.Import className="mr-2 h-4 w-4" />
<span className="hidden sm:ml-2 sm:inline">Confirm Import</span>
</>
)}
Expand Down
4 changes: 2 additions & 2 deletions src/pages/holdings/components/income-dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ export function IncomeDashboard() {
const totalIncome = incomeSummary.total_income;
const dividendIncome = incomeSummary.by_type['DIVIDEND'] || 0;
const interestIncome = incomeSummary.by_type['INTEREST'] || 0;
const dividendPercentage = (dividendIncome / totalIncome) * 100;
const interestPercentage = (interestIncome / totalIncome) * 100;
const dividendPercentage = (dividendIncome / totalIncome) * 100 || 0;
const interestPercentage = (interestIncome / totalIncome) * 100 || 0;

// Filter out interest and only keep dividend income for top stocks
const topDividendStocks = Object.entries(incomeSummary.by_symbol)
Expand Down
27 changes: 13 additions & 14 deletions src/pages/onboarding/onboarding-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ export const OnboardingPage = () => {

const renderStepIcon = (stepNumber: number) => {
return currentStep >= stepNumber ? (
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-green-500">
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-green-500">
<Icons.CheckCircle className="text-xs text-white" />
</div>
) : (
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-foreground/80">
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-foreground/80">
<span className="text-xs text-white">{stepNumber}</span>
</div>
);
};

return (
<section className="flex min-h-screen items-center justify-center pb-16">
<div className=" flex max-w-4xl flex-col space-x-6 md:flex-row md:items-center ">
<div className="flex max-w-4xl flex-col space-x-6 md:flex-row md:items-center">
<div className="md:flex md:w-1/4 md:items-center md:justify-center">
<img
alt="Illustration"
Expand All @@ -37,30 +37,29 @@ export const OnboardingPage = () => {
/>
</div>
<div className="space-y-6 md:w-3/4">
<h1 className="mb-4 text-3xl font-bold text-gray-900 dark:text-gray-100 ">
<h1 className="mb-4 text-3xl font-bold text-gray-900 dark:text-gray-100">
Welcome to Wealthfolio
</h1>
<p className="mb-8 text-lg text-gray-600 dark:text-gray-400">
Your personal financial portfolio tracker, right on your computer. Here's how to get
started:
</p>
<div className="mb-8 space-y-6 pl-2">
<Link to="/settings/general" className="flex items-center space-x-2">
<Link to="/settings/general" className="group flex items-center space-x-2">
{renderStepIcon(1)}
<p className="text-gray-700 dark:text-gray-300">Set your main currency</p>
<Icons.ArrowRight className="ml-2 h-4 w-4" />
</Link>
<Link to="/settings/accounts" className="flex items-center space-x-2">
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-foreground/80">
<span className="text-xs text-white">2</span>
</div>
<Link to="/settings/accounts" className="group flex items-center space-x-2">
{renderStepIcon(2)}
<p className="text-gray-700 dark:text-gray-300">Add your accounts</p>
<Icons.ArrowRight className="ml-2 h-4 w-4" />
</Link>
<div className="flex items-center space-x-2">
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-foreground/80">
<span className="text-xs text-white">3</span>
</div>
<Link to="/activities" className="group flex items-center space-x-2">
{renderStepIcon(3)}
<p className="text-gray-700 dark:text-gray-300">Add or import activities</p>
</div>
<Icons.ArrowRight className="ml-2 h-4 w-4" />
</Link>
</div>
<div>
<Button className="mt-4" asChild>
Expand Down

0 comments on commit 6d9f84b

Please sign in to comment.