aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/components/AnotherComponent.tsx28
-rw-r--r--src/components/FFXIVItemPrice.tsx83
-rw-r--r--src/components/FFXIVWorldSelector.tsx17
-rw-r--r--src/content/blog/ffxiv-gil-making.mdx13
-rw-r--r--src/styles/ffxiv-selector.css72
5 files changed, 172 insertions, 41 deletions
diff --git a/src/components/AnotherComponent.tsx b/src/components/AnotherComponent.tsx
deleted file mode 100644
index f74e924..0000000
--- a/src/components/AnotherComponent.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import React, { useState, useEffect } from 'react';
-
-const AnotherComponent: React.FC = () => {
- const [selectedWorld, setSelectedWorld] = useState<string | null>(null);
-
- useEffect(() => {
- // Load selected world from localStorage
- const savedWorld = localStorage.getItem('selectedWorld');
- if (savedWorld) {
- setSelectedWorld(savedWorld);
- }
- }, []);
-
- return (
- <div>
- <p>Selected World: {selectedWorld}</p>
- <button onClick={() => {
- const newWorld = 'New World';
- setSelectedWorld(newWorld);
- localStorage.setItem('selectedWorld', newWorld); // Save to localStorage
- }}>
- Change World
- </button>
- </div>
- );
-};
-
-export default AnotherComponent; \ No newline at end of file
diff --git a/src/components/FFXIVItemPrice.tsx b/src/components/FFXIVItemPrice.tsx
new file mode 100644
index 0000000..8f265fc
--- /dev/null
+++ b/src/components/FFXIVItemPrice.tsx
@@ -0,0 +1,83 @@
+import React, { useState, useEffect } from 'react';
+
+interface FFXIVItemPriceProps {
+ itemId: number;
+ itemName: string;
+ itemImageUrl: string;
+}
+
+const FFXIVItemPrice: React.FC<FFXIVItemPriceProps> = ({ itemId = 5530, itemName="Coke", itemImageUrl="https://xivapi.com/i/021000/021462_hr1.png"}) => {
+ const [selectedWorld, setSelectedWorld] = useState<string | null>(null);
+ const [dailySaleVelocity, setDailySaleVelocity] = useState<number | null>(null);
+ const [averageSalePrice, setAverageSalePrice] = useState<number | null>(null);
+ const [inputQuantity, setInputQuantity] = useState<number>(0);
+ const [potentialGil, setPotentialGil] = useState<number>(0);
+
+ useEffect(() => {
+ const savedWorld = localStorage.getItem('selectedWorld');
+ if (savedWorld) {
+ setSelectedWorld(savedWorld);
+ } else {
+ setSelectedWorld('Midgardsormr');
+ }
+
+ fetch(`https://universalis.app/api/v2/aggregated/${selectedWorld}/${itemId}`)
+ .then(response => response.json())
+ .then(data => {
+ const result = data.results[0];
+ setDailySaleVelocity(Math.round(result.nq.dailySaleVelocity.world.quantity));
+ setAverageSalePrice(Math.round(result.nq.averageSalePrice.world.price));
+ })
+ .catch(error => console.error('Error fetching data:', error));
+ }, [itemId, selectedWorld]);
+
+ const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ const quantity = parseInt(e.target.value, 10);
+ setInputQuantity(quantity);
+ setPotentialGil(quantity * (averageSalePrice || 0));
+ };
+
+ const formatNumber = (number: number | null) => {
+ return number !== null ? new Intl.NumberFormat().format(number) : 'N/A';
+ };
+
+ return (
+ <div className="ffxiv-container">
+ <div className="ffxiv-header">
+ <h1 className="ffxiv-h1">{itemName}</h1>
+ <img src={itemImageUrl} alt={itemName} className="ffxiv-item-icon" />
+ </div>
+ <table className="ffxiv-table">
+ <tbody>
+ <tr>
+ <td className="ffxiv-label">Daily Sale Velocity:</td>
+ <td className="ffxiv-value">{formatNumber(dailySaleVelocity)} items</td>
+ </tr>
+ <tr>
+ <td className="ffxiv-label">Average Price/Item:</td>
+ <td className="ffxiv-value">{formatNumber(averageSalePrice)} gil</td>
+ </tr>
+ <tr>
+ <td className="ffxiv-label">Enter Quantity:</td>
+ <td>
+ <input
+ type="number"
+ value={inputQuantity}
+ onChange={handleInputChange}
+ placeholder="Enter quantity"
+ className="ffxiv-input"
+ />
+ </td>
+ </tr>
+ <tr>
+ <td className="ffxiv-label">Potential Gil Earnings:</td>
+ <td className="ffxiv-value">{formatNumber(potentialGil)} gil</td>
+ </tr>
+ </tbody>
+ </table>
+ <footer>{selectedWorld} Marketboard Data provided by Universalis API</footer>
+ </div>
+ );
+};
+
+export default FFXIVItemPrice; \ No newline at end of file
diff --git a/src/components/FFXIVWorldSelector.tsx b/src/components/FFXIVWorldSelector.tsx
index f2dc4cc..63eff07 100644
--- a/src/components/FFXIVWorldSelector.tsx
+++ b/src/components/FFXIVWorldSelector.tsx
@@ -1,11 +1,15 @@
import React, { useState, useEffect } from 'react';
-
+import '../styles/ffxiv-selector.css';
interface World {
id: number;
name: string;
}
-const FFXIVWorldSelector: React.FC = () => {
+interface FFXIVWorldSelectorProps {
+ message: string;
+}
+
+const FFXIVWorldSelector: React.FC<FFXIVWorldSelectorProps> = ({ message = "Select a World" }) => {
const [worlds, setWorlds] = useState<World[]>([]);
const [selectedWorld, setSelectedWorld] = useState<string | null>(null);
@@ -40,9 +44,9 @@ const FFXIVWorldSelector: React.FC = () => {
};
return (
- <div>
- <label htmlFor="world-select">Select a world: </label>
- <select id="world-select" onChange={handleWorldChange} value={selectedWorld || ''}>
+ <div className="ffxiv-container">
+ <label htmlFor="world-select" className="ffxiv-label">{message}</label>
+ <select id="world-select" onChange={handleWorldChange} value={selectedWorld || ''} className="ffxiv-select">
<option value="">--Please choose an option--</option>
{worlds.map((world) => (
<option key={world.id} value={world.name}>
@@ -50,8 +54,7 @@ const FFXIVWorldSelector: React.FC = () => {
</option>
))}
</select>
- {selectedWorld && <p>Selected World: {selectedWorld}</p>}
- <button onClick={handleApplyClick}>Apply</button>
+ <button onClick={handleApplyClick} className="ffxiv-button">Apply</button>
</div>
);
};
diff --git a/src/content/blog/ffxiv-gil-making.mdx b/src/content/blog/ffxiv-gil-making.mdx
index 002ab8c..eb35a28 100644
--- a/src/content/blog/ffxiv-gil-making.mdx
+++ b/src/content/blog/ffxiv-gil-making.mdx
@@ -5,15 +5,16 @@ pubDate: "2024-08-23"
---
import '../../styles/ffxiv-gil-making.css'
import FFXIVWorldSelector from '../../components/FFXIVWorldSelector';
-import AnotherComponent from '../../components/AnotherComponent';
-
-*Enter the world you play on below to get crowdsourced marketboard prices*
-<FFXIVWorldSelector client:load />
+import FFXIVItemPrice from '../../components/FFXIVItemPrice';
+<FFXIVWorldSelector client:load message="Set your home world to get crowdsourced marketboard information!" />
I've seen a lot of these "making gil without crafting" or "making gil with combat job" guides during my time with the game.
A lot of these videos and guides are fine, but in my opinion they neglect a lot of the late game and niche options that are available to players.
-This post will attempt to be a somewhat comprehensive guide to making gil without having to level any crafting jobs (cause I get it, crafting is not for everyone).
-<AnotherComponent client:load/> \ No newline at end of file
+This post will attempt to be a somewhat comprehensive guide/info sheet to making gil without having to level any crafting jobs (cause I get it, crafting is not for everyone).
+
+Keep in mind though that crafters are probably one of the most consistent methods of getting gil. There will be a lot more "instability" with these methods.
+
+# Grand Company Seals \ No newline at end of file
diff --git a/src/styles/ffxiv-selector.css b/src/styles/ffxiv-selector.css
new file mode 100644
index 0000000..efad540
--- /dev/null
+++ b/src/styles/ffxiv-selector.css
@@ -0,0 +1,72 @@
+.ffxiv-container {
+ background-color: #1a1a1a;
+ color: #e2c08d;
+ padding: 10px;
+ border: 2px solid #e2c08d;
+ border-radius: 10px;
+ font-family: 'Arial', serif;
+ max-width: 500px;
+ margin: auto;
+}
+
+.ffxiv-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 10px;
+}
+
+.ffxiv-item-icon {
+ width: 50px;
+ height: 50px;
+}
+
+.ffxiv-h1 {
+ font-size: 1.5em;
+ color: #e2c08d;
+ margin: 0;
+}
+
+.ffxiv-table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+.ffxiv-button {
+ background-color: #333;
+ color: #e2c08d;
+ border: 1px solid #e2c08d;
+ padding: 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ margin-left: 10px;
+ border-radius: 5px;
+ cursor: pointer;
+}
+
+.ffxiv-table td {
+ padding: 5px;
+ border: 1px solid #e2c08d;
+}
+
+.ffxiv-label {
+ font-size: 1em;
+}
+
+.ffxiv-value {
+ font-size: 1em;
+}
+
+.ffxiv-input {
+ background-color: #333;
+ color: #e2c08d;
+ border: 1px solid #e2c08d;
+ padding: 5px;
+ border-radius: 5px;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.ffxiv-input::placeholder {
+ color: #e2c08d;
+} \ No newline at end of file
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage