Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
84dd97c
feat: services for accounts, desposits and payouts
Paulijuz Mar 10, 2025
9716f0a
feat: payments
Paulijuz Mar 11, 2025
fdc90c0
feat: transaction paging
Paulijuz Mar 12, 2025
a545516
refactor: rename lib/money to lib/currency
Paulijuz Mar 13, 2025
25e94f8
feat: money stuff
Paulijuz Mar 13, 2025
bd01d6a
chore: update package lock
Paulijuz Apr 27, 2025
121e5d0
chore: update ledger methods to use schemas
Paulijuz Apr 27, 2025
32e5246
refactor: stripe event handling
Paulijuz Apr 30, 2025
4b4bb40
feat: ledger schema
Paulijuz Aug 10, 2025
88e947f
feat: payment service
Paulijuz Aug 10, 2025
0e86994
feat: balance calculation
Paulijuz Aug 11, 2025
7d7f43b
refactor: simplify relation between transaction and entries/payment/p…
Paulijuz Aug 15, 2025
5b82357
feat: transaction validation logic
Paulijuz Aug 15, 2025
3d6e24e
feat: more ledger transaction validation
Paulijuz Aug 20, 2025
68f5d32
feat: ledger operations
Paulijuz Aug 20, 2025
8d7f0b8
chore: clean up commented out code
Paulijuz Aug 20, 2025
9c86fca
feat: add manual transfer to schema (forgot to commit this)
Paulijuz Aug 20, 2025
c2a64b7
test: beginning of ledger tests
Paulijuz Aug 20, 2025
d4e9d01
feat: add reason for why transaction failed
Paulijuz Aug 21, 2025
177b41b
style: always use state in stead of status
Paulijuz Aug 21, 2025
ed2326b
fix: set default balance to zero
Paulijuz Aug 21, 2025
736eca2
test: calculate fees test
Paulijuz Aug 21, 2025
173ff8f
fix: calculate fees logic
Paulijuz Aug 21, 2025
308efd6
fix: disable mail sending during testing
Paulijuz Aug 21, 2025
841cf9c
fix: disable email rendering during testing
Paulijuz Aug 21, 2025
3d3dc3e
feat: promis util for tests
Paulijuz Aug 21, 2025
16c0f53
fiix: actually disable mail sending during testing
Paulijuz Aug 21, 2025
ec99d01
context: tests
Paulijuz Aug 21, 2025
dd8d8a8
test: ledger transaction tests
Paulijuz Aug 21, 2025
d0c57e4
fix: package-lock.json after rebase
Paulijuz Aug 21, 2025
3e1de12
feat: add ui from my other computer
Paulijuz Aug 22, 2025
86a673c
refactor: improve services to make UI easier
Paulijuz Aug 25, 2025
02a60ea
feat: ui and the like
Paulijuz Aug 29, 2025
12ef564
style: linting
Paulijuz Sep 21, 2025
29738ca
refactor: reorganize UI components (no work)
Paulijuz Sep 21, 2025
2a8c869
feat: more boring ui cleanup
Paulijuz Sep 21, 2025
4527f2a
feat: working transaction lists ++
Paulijuz Sep 22, 2025
c156d17
feat: ledger list ui polish
Paulijuz Sep 22, 2025
f832d58
style: linting, linting and more linting
Paulijuz Sep 23, 2025
6e280b9
feat: save payment method
Paulijuz Sep 23, 2025
626e3ff
Merge branch 'main' into feat/ledger
Paulijuz Jan 6, 2026
da9c005
chore: update services naming convention
Paulijuz Jan 6, 2026
a792bb6
fix: eslint errors
Paulijuz Jan 6, 2026
ff3292d
fix: build errors
Paulijuz Jan 6, 2026
157008e
chore: fix merge conflic errors in package lock
Paulijuz Jan 6, 2026
1f14fa4
feat: freezing of accounts
Paulijuz Jan 6, 2026
dcb1f1a
feat: removal of card
Paulijuz Jan 12, 2026
a89e4a7
fix: group account page loading
Paulijuz Jan 12, 2026
acdc733
refactor: rename ledger operation operations to ledger movement opera…
Paulijuz Jan 12, 2026
09193a1
style: linting
Paulijuz Jan 12, 2026
3715d8a
fix: account page not loading with missing keys
Paulijuz Jan 12, 2026
6366208
Merge branch 'main' into feat/ledger
Paulijuz Jan 12, 2026
0722b22
fix: broken test
Paulijuz Jan 13, 2026
8c20911
style: linting
Paulijuz Jan 19, 2026
b0b685c
fix: make console errors from next auth
Paulijuz Jan 19, 2026
7d40b4e
feat: remember pop uip in url
Paulijuz Jan 19, 2026
c852574
style: linting
Paulijuz Jan 19, 2026
dd97ef8
fix: pop up component prop type
Paulijuz Jan 19, 2026
ceafbf6
Merge branch 'main' into feat/ledger
Paulijuz Jan 19, 2026
e66a1c6
fix: use useEffectEvent in pop up
Paulijuz Jan 19, 2026
3d214e7
refactor: remove unused checkout modal for now
Paulijuz Jan 19, 2026
e072e7d
fix: minor issues with setting manual fees
Paulijuz Jan 19, 2026
96a1015
Merge branch 'main' into feat/ledger
Paulijuz Jan 21, 2026
5560f20
style: linting
Paulijuz Jan 21, 2026
4ec7725
chore: update readme with test command and add lint fix command
Paulijuz Jan 21, 2026
3b789e9
Merge branch 'main' into feat/ledger
Paulijuz Jan 21, 2026
2629005
style: linting
Paulijuz Jan 21, 2026
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
5 changes: 5 additions & 0 deletions .env.default
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ LOG_MAX_FILES=365
NEXTAUTH_URL="http://localhost"
NEXTAUTH_SECRET=cake_is_love_cake_is_life

# Stripe
STRIPE_SECRET_KEY=sk_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_...
STRIPE_WEBHOOK_SECRET=whsec_...

# Password Hashing and Encryption
PASSWORD_SALT_ROUNDS="12"
PASSWORD_ENCRYPTION_KEY="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" # Must be 256 bits (43 characters) long
Expand Down
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ npm run lint
To auto-fix linting errors run

```bash
npm run lint -- --fix
npm run lint:fix
```

## Migration from omegaweb basic
Expand All @@ -92,3 +92,16 @@ npm run dobbelOmega:run
```

If you are connected to our test database on openStack, make sure to be on the ntnu network to be able to connect.

## Testing

To run the tests run
```bash
npm run docker:test
```

The tests can also be run outside of docker using
```bash
npm run test
```
but this requires starting a database manually.
4 changes: 3 additions & 1 deletion docker-compose.base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ services:
API_KEY_ENCRYPTION_KEY: ${API_KEY_ENCRYPTION_KEY}
FEIDE_CLIENT_ID: ${FEIDE_CLIENT_ID}
FEIDE_CLIENT_SECRET: ${FEIDE_CLIENT_SECRET}
MAIL_SERVER: ${MAIL_SERVER}
STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY}
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: ${NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY}
STRIPE_WEBHOOK_SECRET: ${STRIPE_WEBHOOK_SECRET}
MAIL_DOMAIN: ${MAIL_DOMAIN}
DOMAIN: ${DOMAIN}
JWT_PRIVATE_KEY: ${JWT_PRIVATE_KEY}
Expand Down
2 changes: 1 addition & 1 deletion eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ const eslintConfig = defineConfig([
// specify the maximum depth callbacks can be nested
'max-nested-callbacks': [
'error',
3
4
],
// disallow the omission of parentheses when invoking a constructor with no arguments
'new-parens': 'error',
Expand Down
5 changes: 5 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const config: Config = {
// This is needed becaue jest doesn't handle the this code is inside node_modules
'^@/prisma-dobbel-omega/(.*)$': '<rootDir>/node_modules/.prisma-dobbel-omega/$1',
},
globals: {
'ts-jest': {
useESM: true,
},
}
}

export default async function jestConfig() {
Expand Down
80 changes: 77 additions & 3 deletions package-lock.json

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

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"build": "next build",
"start": "next start",
"lint": "eslint",
"lint:fix": "eslint --fix --quiet",
"test": "IGNORE_SERVER_ONLY=true jest",
"docker:dev": "./development-entrypoint.sh",
"docker:test": "docker compose -f docker-compose.test.yml up --build --abort-on-container-exit --exit-code-from projectnext --attach projectnext --no-log-prefix",
Expand All @@ -27,6 +28,8 @@
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/free-solid-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.2",
"@stripe/react-stripe-js": "^3.3.0",
"@stripe/stripe-js": "^5.9.2",
"@prisma/adapter-pg": "^7.2.0",
"@prisma/client": "^7.2.0",
"@react-email/components": "^0.5.7",
Expand All @@ -53,6 +56,7 @@
"remark-rehype": "^11.1.2",
"sass": "^1.93.2",
"server-only": "^0.0.1",
"stripe": "^17.7.0",
"sharp": "^0.34.4",
"unified": "^11.0.5",
"uuid": "^10.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@use "@/styles/ohma";

.LedgerAccountBalance {
display: grid;
grid-template-columns: auto 1fr auto;
grid-auto-flow: row;
grid-auto-columns: max-content;
column-gap: 2*ohma.$gap;
white-space: nowrap;
overflow: hidden;

// @include ohma.screenMobile {
// grid-template-columns: auto 1fr;
// }
// align-items: center;
// justify-content: space-between;
}

.amountRow {
display: contents;
font-size: ohma.$fonts-xxl;
}

.feesRow {
display: contents;
font-size: ohma.$fonts-l;
}

.total {
text-align: right;
// width: 100%; // ensures it stretches to the container
}
26 changes: 26 additions & 0 deletions src/app/_components/Ledger/Accounts/LedgerAccountBalance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import styles from './LedgerAccountBalance.module.scss'
import { unwrapActionReturn } from '@/app/redirectToErrorPage'
import { displayAmount } from '@/lib/currency/convert'
import { calculateLedgerAccountBalanceAction } from '@/services/ledger/accounts/actions'

type Props = {
ledgerAccountId: number,
showFees?: boolean,
}

export default async function LedgerAccountBalance({ ledgerAccountId: accountId, showFees }: Props) {
const balance = unwrapActionReturn(await calculateLedgerAccountBalanceAction({ params: { id: accountId } }))

return <div className={styles.LedgerAccountBalance}>
<div className={styles.amountRow}>
<div>Saldo</div>
<div className={styles.total}>{displayAmount(balance.amount)}</div>
<div className={styles.currencySymbol}>Muenter</div>
</div>
{showFees && <div className={styles.feesRow}>
<div>Avgifter</div>
<div className={styles.total}>{displayAmount(balance.fees)}</div>
<div className={styles.currencySymbol}>Muenter</div>
</div>}
</div>
}
32 changes: 32 additions & 0 deletions src/app/_components/Ledger/Accounts/LedgerAccountFreezeButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use client'

import Button from '@/components/UI/Button'
import { updateLedgerAccountAction } from '@/services/ledger/accounts/actions'
import { useRouter } from 'next/navigation'
import type { LedgerAccount } from '@/prisma-generated-pn-types'

export default function LedgerAccountFreezeButton({
ledgerAccount,
className
}: { ledgerAccount: LedgerAccount, className?: string }) {
const { refresh } = useRouter()

const toggleFrozen = async () => {
await updateLedgerAccountAction({
params: {
id: ledgerAccount.id,
},
}, {
data: {
frozen: !ledgerAccount.frozen,
}
})
refresh()
}

return (
<Button color="secondary" className={className} onClick={toggleFrozen}>
{ledgerAccount.frozen ? 'Tin konto' : 'Frys konto'}
</Button>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@use "@/styles/ohma";

.ledgerAccountListTable {
@include ohma.table();
}
31 changes: 31 additions & 0 deletions src/app/_components/Ledger/Accounts/LedgerAccountList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use client'

import styles from './LedgerAccountList.module.scss'
import EndlessScroll from '@/components/PagingWrappers/EndlessScroll'
import { LedgerAccountPagingProvider, LedgerAccountPagingContext } from '@/contexts/paging/LedgerAccountPaging'
import Link from 'next/link'

export default function LedgerAccountList() {
return <LedgerAccountPagingProvider
startPage={{ page: 0, pageSize: 10 }}
details={{ accountType: 'GROUP' }}
serverRenderedData={[]}
>
<table className={styles.ledgerAccountListTable}>
<thead>
<tr>
<th>Navn</th>
<th>Saldo</th>
</tr>
</thead>
<tbody>
<EndlessScroll pagingContext={LedgerAccountPagingContext} renderer={account =>
<tr key={account.id}>
<td><Link href={`accounts/${account.id}`}>{account.name}</Link></td>
<td>19.19 Klinguende Muente</td>
</tr>
}/>
</tbody>
</table>
</LedgerAccountPagingProvider>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@use "@/styles/ohma";

.frozenStatus {
color: red;

.frozenWarningHidden {
visibility: hidden;
}
}

.ledgerAccountOverviewButtons {
margin-top: 3*ohma.$gap;
display: flex;
flex-direction: row;

.rightAligned {
margin-left: auto;
}
}
Loading
Loading