Skip to content

Commit 0890ced

Browse files
Support creation of transactions in SPA prototype
1 parent 5b35d73 commit 0890ced

File tree

5 files changed

+108
-1
lines changed

5 files changed

+108
-1
lines changed

app/Http/Controllers/Api/TransactionController.php

+42
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,46 @@ public function index(Request $request)
3333

3434
return TransactionResource::collection($transactions);
3535
}
36+
37+
public function store(Request $request)
38+
{
39+
$apiKey = ApiKey::query()
40+
->where('token', $request->header('api-key'))
41+
->first();
42+
43+
if (!$apiKey) {
44+
abort(401);
45+
}
46+
47+
$spaceId = $apiKey->user->spaces()->first()->id;
48+
49+
$request->validate([
50+
'type' => 'in:earning,spending',
51+
// TODO
52+
]);
53+
54+
if ($request->input('type') === 'earning') {
55+
Earning::create([
56+
'space_id' => $spaceId,
57+
'recurring_id' => null, // TODO
58+
'happened_on' => $request->input('happened_on'),
59+
'description' => $request->input('description'),
60+
'amount' => $request->input('amount')
61+
]);
62+
}
63+
64+
if ($request->input('type') === 'spending') {
65+
Spending::create([
66+
'space_id' => $spaceId,
67+
'import_id' => null, // TODO
68+
'recurring_id' => null, // TODO
69+
'tag_id' => null, // TODO
70+
'happened_on' => $request->input('happened_on'),
71+
'description' => $request->input('description'),
72+
'amount' => $request->input('amount')
73+
]);
74+
}
75+
76+
return [];
77+
}
3678
}

resources/assets/js/prototype/app.js

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import App from './components/App.vue';
66
import Login from './screens/Login.vue';
77
import Dashboard from './screens/Dashboard.vue';
88
import TransactionsIndex from './screens/Transactions/Index.vue';
9+
import TransactionsCreate from './screens/Transactions/Create.vue';
910

1011
Vue.use(VueRouter);
1112

@@ -22,6 +23,10 @@ const routes = [
2223
path: '/prototype/transactions',
2324
name: 'transactions.index',
2425
component: TransactionsIndex,
26+
}, {
27+
path: '/prototype/transactions/create',
28+
name: 'transactions.create',
29+
component: TransactionsCreate,
2530
},
2631
];
2732

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<script setup>
2+
import axios from 'axios';
3+
import { ref } from 'vue';
4+
5+
import Navigation from '../../components/Navigation.vue';
6+
7+
const type = ref('earning');
8+
const happened_on = ref('2023-11-02');
9+
const description = ref('');
10+
const amount = ref(10.00);
11+
12+
const create = () => {
13+
axios.post('/api/transactions', {
14+
type: type.value,
15+
happened_on: happened_on.value,
16+
description: description.value,
17+
amount: amount.value,
18+
}, {
19+
headers: {
20+
'api-key': localStorage.getItem('api_key'),
21+
},
22+
})
23+
.then(() => {
24+
alert('wtf, dat werkte');
25+
})
26+
.catch(() => {
27+
alert('Something went wrong');
28+
});
29+
};
30+
</script>
31+
32+
<template>
33+
<div>
34+
<Navigation />
35+
<div class="max-w-sm mx-auto my-10 space-y-5">
36+
<div class="flex space-x-3">
37+
<button class="px-4 py-2 text-sm border border-gray-200 rounded-md" :class="{ 'bg-gray-100': type === 'earning' }" @click="type = 'earning'">Earning</button>
38+
<button class="px-4 py-2 text-sm border border-gray-200 rounded-md" :class="{ 'bg-gray-100': type === 'spending' }" @click="type = 'spending'">Spending</button>
39+
</div>
40+
<div v-if="type === 'spending'">
41+
<label class="mb-1 block text-sm">Tag</label>
42+
<input class="w-full px-3 py-2 text-sm border rounded-md" type="text" value="Coming soon" disabled />
43+
</div>
44+
<div>
45+
<label class="mb-1 block text-sm">Date</label>
46+
<input class="w-full px-3 py-2 text-sm border rounded-md" type="text" v-model="happened_on" />
47+
</div>
48+
<div>
49+
<label class="mb-1 block text-sm">Description</label>
50+
<input class="w-full px-3 py-2 text-sm border rounded-md" type="text" :placeholder="type === 'earning' ? 'Paycheck February' : 'Birthday present for Angela'" v-model="description" />
51+
</div>
52+
<div>
53+
<label class="mb-1 block text-sm">Amount</label>
54+
<input class="w-full px-3 py-2 text-sm border rounded-md" type="text" v-model="amount" />
55+
</div>
56+
<button class="px-4 py-2 text-sm border border-gray-200 rounded-md" @click="create()">Create</button>
57+
</div>
58+
</div>
59+
</template>

routes/api.php

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@
77
Route::post('/log-in', LogInController::class);
88

99
Route::get('/transactions', [TransactionController::class, 'index']);
10+
Route::post('/transactions', [TransactionController::class, 'store']);

routes/web.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,5 @@
135135
Route::prefix('prototype')
136136
->group(function () {
137137
Route::get('/', fn () => 'Hello world');
138-
Route::get('/{any}', \App\Http\Controllers\PrototypeController::class);
138+
Route::get('/{any}', \App\Http\Controllers\PrototypeController::class)->where('any', '.*');
139139
});

0 commit comments

Comments
 (0)