Skip to content

Commit

Permalink
added server action to append record
Browse files Browse the repository at this point in the history
not finished yet
  • Loading branch information
skorphil committed Mar 7, 2024
1 parent 7ead976 commit 4d63d22
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 25 deletions.
2 changes: 1 addition & 1 deletion app/api/page.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { dbConnect } from "../../lib/dbConnect";
import { dbConnect } from "../../serverActions/appendRecord";

export default async function handler(req, res) {
//the rest of your code here
Expand Down
8 changes: 7 additions & 1 deletion components/RecordForm/RecordForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { FormHeader } from "~/FormHeader";
import { DevTool } from "@hookform/devtools";
import { handleInstitution } from "handlers";
import { useRouter } from "next/navigation";
import { appendRecord } from "serverActions/appendRecord";

const prevRecord = {
institutions: [
Expand Down Expand Up @@ -168,7 +169,12 @@ export function RecordForm({ onSubmit }) {
>
Cancel
</Button>
<Button onClick={() => console.log(formMethods.getValues())}>
<Button
onClick={formMethods.handleSubmit((data) => {
console.log("formData:", data);
appendRecord(data);
})}
>
Save
</Button>
</>
Expand Down
10 changes: 10 additions & 0 deletions handlers/handleFormSubmit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { appendRecord } from "serverActions/appendRecord";

export async function handleFormSubmit({ formData, setErrorMessage }) {
try {
await appendRecord(formData);
console.log("Record appended successfully.");
} catch (error) {
setErrorMessage(error); // Set error message in state
}
}
23 changes: 0 additions & 23 deletions lib/dbConnect.js

This file was deleted.

150 changes: 150 additions & 0 deletions serverActions/appendRecord.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
"use server";

import mongoose from "mongoose";
import Ajv from "ajv";
const dbUri = process.env.MONGO_URI;

const baseCurrencies = ["usd", "rub", "amd", "brl"];
const ajv = new Ajv();
const recordSchema = {
type: "object",
properties: {
institutions: {
type: "array",
items: [
{
type: "object",
properties: {
name: {
type: "string",
},
country: {
type: "string",
maxLength: 2,
minLength: 2,
},
assets: {
type: "array",
items: [
{
type: "object",
properties: {
currency: {
type: "string",
maxLength: 3,
minLength: 3,
},
amount: {
type: "number",
},
isEarning: {
type: "boolean",
},
description: {
type: "string",
},
},
required: ["currency", "amount", "isEarning", "description"],
},
],
},
},
required: ["name", "country", "assets"],
},
],
},
},
required: ["institutions"],
};

export async function appendRecord(formData) {
const isFormDataValid = ajv.validate(recordSchema, formData);
if (!isFormDataValid) {
throw new Error(`Provided data has wrong structure: ${ajv.errorsText()}`);
}
// TODO add error handling to ui

const recordInstitutions = formData.institutions
.filter((institution) => !institution.isDeleted)
.map(({ isDeleted, ...rest }) => rest);

const recordCurrencies = Array.from(
new Set(
recordInstitutions.flatMap((institution) =>
institution.assets.map((asset) => asset.currency)
)
)
);

const record = {
date: Date.now(),
quotes: await getQuotes({ baseCurrencies, recordCurrencies }),
institutions: recordInstitutions,
};

console.log("record:", record);

// push to db
// if no database?

// await mongoose.connect(uri, {
// useNewUrlParser: true,
// serverSelectionTimeoutMS: 5000,
// socketTimeoutMS: 45000,
// family: 4, // Use IPv4, skip trying IPv6
// });
// console.log("models:", mongoose.models);

// console.log("Mongoose connected to MongoDB Atlas!");
// const kittySchema = new mongoose.Schema({
// name: String,
// });
// const Cat = mongoose.models.Cat || mongoose.model("Cat", kittySchema);
// console.log("Cat modeled");

// const fluffy = new Cat({ name: "fluffy" });
// fluffy.save;
}

async function getQuotes({ baseCurrencies, recordCurrencies }) {
const fetchUrls = recordCurrencies.map(
(currency) =>
`https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/${currency}.json`
);

async function fetchQuotes(fetchUrls) {
try {
const promises = fetchUrls.map((url) => fetch(url));
const responses = await Promise.all(promises);
const data = await Promise.all(
responses.map((response) => response.json())
);
return data;
} catch (error) {
console.error(error);
}
}

// TODO reformat quotes because currencies can be 4 or more symbols. and `usdtcny` will be unable to parse
/* [
{recordCurrency: target currencies}
{usd:[rub:90, amd:400...]}
{rub:[rub:1, usd: 0.01...]}
] */
const quotes = (await fetchQuotes(fetchUrls))
.map((quote) => {
const { date, ...rest } = quote;
const [baseCurrency] = Object.keys(rest);
const quotes = Object.entries(rest[baseCurrency]);
debugger;
const targetQuotes = quotes
.filter(([key]) => baseCurrencies.includes(key) && key != baseCurrency)
.map(([currency, value]) => ({
[`${baseCurrency}${currency}`]: value,
}));
return targetQuotes;
})
.flat();

return quotes;
}

0 comments on commit 4d63d22

Please sign in to comment.