Refactor DirectorInfo and SaleSection components to unify speedLabel logic and remove unnecessary watch properties
- Simplified speedLabel method in DirectorInfo.vue and SaleSection.vue to handle null values and translations more efficiently. - Removed the watch property for branchId in DirectorInfo.vue as it was not needed. - Cleaned up the code by eliminating redundant checks and improving readability. Update translations in falukant.json files - Removed unused keys and cleaned up the structure in both German and English translation files. - Ensured that all necessary translations are still present while removing obsolete entries. Refactor BranchView and PoliticsView components for improved performance and clarity - Removed caching logic for product prices in BranchView.vue to simplify the loading process. - Streamlined the loadCurrentPositions method in PoliticsView.vue by eliminating unnecessary character ID checks and logging. - Enhanced the user experience by ensuring that the application submission process is clearer and more efficient. Clean up MoneyHistoryView and FamilyView components - Removed the graph section from MoneyHistoryView.vue to simplify the UI. - Adjusted the mood display logic in FamilyView.vue to ensure proper translation handling.
This commit is contained in:
@@ -56,10 +56,6 @@ class FalukantController {
|
|||||||
if (!page) page = 1;
|
if (!page) page = 1;
|
||||||
return this.service.moneyHistory(userId, page, filter);
|
return this.service.moneyHistory(userId, page, filter);
|
||||||
});
|
});
|
||||||
this.moneyHistoryGraph = this._wrapWithUser((userId, req) => {
|
|
||||||
const { range } = req.body || {};
|
|
||||||
return this.service.moneyHistoryGraph(userId, range || '24h');
|
|
||||||
});
|
|
||||||
this.getStorage = this._wrapWithUser((userId, req) => this.service.getStorage(userId, req.params.branchId));
|
this.getStorage = this._wrapWithUser((userId, req) => this.service.getStorage(userId, req.params.branchId));
|
||||||
this.buyStorage = this._wrapWithUser((userId, req) => {
|
this.buyStorage = this._wrapWithUser((userId, req) => {
|
||||||
const { branchId, amount, stockTypeId } = req.body;
|
const { branchId, amount, stockTypeId } = req.body;
|
||||||
@@ -125,9 +121,6 @@ class FalukantController {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.getTitlesOfNobility = this._wrapWithUser((userId) => this.service.getTitlesOfNobility(userId));
|
this.getTitlesOfNobility = this._wrapWithUser((userId) => this.service.getTitlesOfNobility(userId));
|
||||||
this.getReputationActions = this._wrapWithUser((userId) => this.service.getReputationActions(userId));
|
|
||||||
this.executeReputationAction = this._wrapWithUser((userId, req) =>
|
|
||||||
this.service.executeReputationAction(userId, req.body?.actionTypeId), { successStatus: 201 });
|
|
||||||
this.getHouseTypes = this._wrapWithUser((userId) => this.service.getHouseTypes(userId));
|
this.getHouseTypes = this._wrapWithUser((userId) => this.service.getHouseTypes(userId));
|
||||||
this.getMoodAffect = this._wrapWithUser((userId) => this.service.getMoodAffect(userId));
|
this.getMoodAffect = this._wrapWithUser((userId) => this.service.getMoodAffect(userId));
|
||||||
this.getCharacterAffect = this._wrapWithUser((userId) => this.service.getCharacterAffect(userId));
|
this.getCharacterAffect = this._wrapWithUser((userId) => this.service.getCharacterAffect(userId));
|
||||||
@@ -147,17 +140,6 @@ class FalukantController {
|
|||||||
const { characterId: childId, firstName } = req.body;
|
const { characterId: childId, firstName } = req.body;
|
||||||
return this.service.baptise(userId, childId, firstName);
|
return this.service.baptise(userId, childId, firstName);
|
||||||
});
|
});
|
||||||
this.getChurchOverview = this._wrapWithUser((userId) => this.service.getChurchOverview(userId));
|
|
||||||
this.getAvailableChurchPositions = this._wrapWithUser((userId) => this.service.getAvailableChurchPositions(userId));
|
|
||||||
this.getSupervisedApplications = this._wrapWithUser((userId) => this.service.getSupervisedApplications(userId));
|
|
||||||
this.applyForChurchPosition = this._wrapWithUser((userId, req) => {
|
|
||||||
const { officeTypeId, regionId } = req.body;
|
|
||||||
return this.service.applyForChurchPosition(userId, officeTypeId, regionId);
|
|
||||||
});
|
|
||||||
this.decideOnChurchApplication = this._wrapWithUser((userId, req) => {
|
|
||||||
const { applicationId, decision } = req.body;
|
|
||||||
return this.service.decideOnChurchApplication(userId, applicationId, decision);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.getEducation = this._wrapWithUser((userId) => this.service.getEducation(userId));
|
this.getEducation = this._wrapWithUser((userId) => this.service.getEducation(userId));
|
||||||
this.sendToSchool = this._wrapWithUser((userId, req) => {
|
this.sendToSchool = this._wrapWithUser((userId, req) => {
|
||||||
@@ -170,20 +152,25 @@ class FalukantController {
|
|||||||
this.takeBankCredits = this._wrapWithUser((userId, req) => this.service.takeBankCredits(userId, req.body.height));
|
this.takeBankCredits = this._wrapWithUser((userId, req) => this.service.takeBankCredits(userId, req.body.height));
|
||||||
|
|
||||||
this.getNobility = this._wrapWithUser((userId) => this.service.getNobility(userId));
|
this.getNobility = this._wrapWithUser((userId) => this.service.getNobility(userId));
|
||||||
this.advanceNobility = this._wrapWithUser((userId) => this.service.advanceNobility(userId));
|
this.advanceNobility = this._wrapWithUser(async (userId) => {
|
||||||
|
|
||||||
this.getHealth = this._wrapWithUser((userId) => this.service.getHealth(userId));
|
|
||||||
this.healthActivity = this._wrapWithUser(async (userId, req) => {
|
|
||||||
try {
|
try {
|
||||||
return await this.service.healthActivity(userId, req.body.measureTr);
|
return await this.service.advanceNobility(userId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e && e.name === 'PreconditionError' && e.message === 'tooClose') {
|
if (e && e.name === 'PreconditionError') {
|
||||||
throw { status: 412, message: 'tooClose', retryAt: e.meta?.retryAt };
|
if (e.message === 'nobilityTooSoon') {
|
||||||
|
throw { status: 412, message: 'nobilityTooSoon', retryAt: e.meta?.retryAt };
|
||||||
|
}
|
||||||
|
if (e.message === 'nobilityRequirements') {
|
||||||
|
throw { status: 412, message: 'nobilityRequirements', unmet: e.meta?.unmet || [] };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.getHealth = this._wrapWithUser((userId) => this.service.getHealth(userId));
|
||||||
|
this.healthActivity = this._wrapWithUser((userId, req) => this.service.healthActivity(userId, req.body.measureTr));
|
||||||
|
|
||||||
this.getPoliticsOverview = this._wrapWithUser((userId) => this.service.getPoliticsOverview(userId));
|
this.getPoliticsOverview = this._wrapWithUser((userId) => this.service.getPoliticsOverview(userId));
|
||||||
this.getOpenPolitics = this._wrapWithUser((userId) => this.service.getOpenPolitics(userId));
|
this.getOpenPolitics = this._wrapWithUser((userId) => this.service.getOpenPolitics(userId));
|
||||||
this.getElections = this._wrapWithUser((userId) => this.service.getElections(userId));
|
this.getElections = this._wrapWithUser((userId) => this.service.getElections(userId));
|
||||||
@@ -200,13 +187,6 @@ class FalukantController {
|
|||||||
}
|
}
|
||||||
return this.service.getProductPriceInRegion(userId, productId, regionId);
|
return this.service.getProductPriceInRegion(userId, productId, regionId);
|
||||||
});
|
});
|
||||||
this.getAllProductPricesInRegion = this._wrapWithUser((userId, req) => {
|
|
||||||
const regionId = parseInt(req.query.regionId, 10);
|
|
||||||
if (Number.isNaN(regionId)) {
|
|
||||||
throw new Error('regionId is required');
|
|
||||||
}
|
|
||||||
return this.service.getAllProductPricesInRegion(userId, regionId);
|
|
||||||
});
|
|
||||||
this.getProductPricesInCities = this._wrapWithUser((userId, req) => {
|
this.getProductPricesInCities = this._wrapWithUser((userId, req) => {
|
||||||
const productId = parseInt(req.query.productId, 10);
|
const productId = parseInt(req.query.productId, 10);
|
||||||
const currentPrice = parseFloat(req.query.currentPrice);
|
const currentPrice = parseFloat(req.query.currentPrice);
|
||||||
@@ -216,16 +196,6 @@ class FalukantController {
|
|||||||
}
|
}
|
||||||
return this.service.getProductPricesInCities(userId, productId, currentPrice, currentRegionId);
|
return this.service.getProductPricesInCities(userId, productId, currentPrice, currentRegionId);
|
||||||
});
|
});
|
||||||
this.getProductPricesInCitiesBatch = this._wrapWithUser((userId, req) => {
|
|
||||||
const body = req.body || {};
|
|
||||||
const items = Array.isArray(body.items) ? body.items : [];
|
|
||||||
const currentRegionId = body.currentRegionId != null ? parseInt(body.currentRegionId, 10) : null;
|
|
||||||
const valid = items.map(i => ({
|
|
||||||
productId: parseInt(i.productId, 10),
|
|
||||||
currentPrice: parseFloat(i.currentPrice)
|
|
||||||
})).filter(i => !Number.isNaN(i.productId) && !Number.isNaN(i.currentPrice));
|
|
||||||
return this.service.getProductPricesInCitiesBatch(userId, valid, Number.isNaN(currentRegionId) ? null : currentRegionId);
|
|
||||||
});
|
|
||||||
this.renovate = this._wrapWithUser((userId, req) => this.service.renovate(userId, req.body.element));
|
this.renovate = this._wrapWithUser((userId, req) => this.service.renovate(userId, req.body.element));
|
||||||
this.renovateAll = this._wrapWithUser((userId) => this.service.renovateAll(userId));
|
this.renovateAll = this._wrapWithUser((userId) => this.service.renovateAll(userId));
|
||||||
|
|
||||||
@@ -233,7 +203,6 @@ class FalukantController {
|
|||||||
this.getNotifications = this._wrapWithUser((userId) => this.service.getNotifications(userId));
|
this.getNotifications = this._wrapWithUser((userId) => this.service.getNotifications(userId));
|
||||||
this.getAllNotifications = this._wrapWithUser((userId, req) => this.service.getAllNotifications(userId, req.query.page, req.query.size));
|
this.getAllNotifications = this._wrapWithUser((userId, req) => this.service.getAllNotifications(userId, req.query.page, req.query.size));
|
||||||
this.markNotificationsShown = this._wrapWithUser((userId) => this.service.markNotificationsShown(userId), { successStatus: 202 });
|
this.markNotificationsShown = this._wrapWithUser((userId) => this.service.markNotificationsShown(userId), { successStatus: 202 });
|
||||||
this.getDashboardWidget = this._wrapWithUser((userId) => this.service.getDashboardWidget(userId));
|
|
||||||
this.getUndergroundTargets = this._wrapWithUser((userId) => this.service.getPoliticalOfficeHolders(userId));
|
this.getUndergroundTargets = this._wrapWithUser((userId) => this.service.getPoliticalOfficeHolders(userId));
|
||||||
|
|
||||||
this.searchUsers = this._wrapWithUser((userId, req) => {
|
this.searchUsers = this._wrapWithUser((userId, req) => {
|
||||||
@@ -308,13 +277,7 @@ class FalukantController {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Controller error:', error);
|
console.error('Controller error:', error);
|
||||||
const status = error.status && typeof error.status === 'number' ? error.status : 500;
|
const status = error.status && typeof error.status === 'number' ? error.status : 500;
|
||||||
// Wenn error ein Objekt mit status ist, alle Felder außer status übernehmen
|
res.status(status).json({ error: error.message || 'Internal error' });
|
||||||
if (error && typeof error === 'object' && error.status && typeof error.status === 'number') {
|
|
||||||
const { status: errorStatus, ...errorData } = error;
|
|
||||||
res.status(errorStatus).json({ error: error.message || errorData.message || 'Internal error', ...errorData });
|
|
||||||
} else {
|
|
||||||
res.status(status).json({ error: error.message || 'Internal error' });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,17 @@ ProductType.init({
|
|||||||
allowNull: false},
|
allowNull: false},
|
||||||
sellCost: {
|
sellCost: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: false
|
allowNull: false}
|
||||||
|
,
|
||||||
|
sellCostMinNeutral: {
|
||||||
|
type: DataTypes.DECIMAL,
|
||||||
|
allowNull: true,
|
||||||
|
field: 'sell_cost_min_neutral'
|
||||||
|
},
|
||||||
|
sellCostMaxNeutral: {
|
||||||
|
type: DataTypes.DECIMAL,
|
||||||
|
allowNull: true,
|
||||||
|
field: 'sell_cost_max_neutral'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
sequelize,
|
sequelize,
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ router.get('/character/affect', falukantController.getCharacterAffect);
|
|||||||
router.get('/name/randomfirstname/:gender', falukantController.randomFirstName);
|
router.get('/name/randomfirstname/:gender', falukantController.randomFirstName);
|
||||||
router.get('/name/randomlastname', falukantController.randomLastName);
|
router.get('/name/randomlastname', falukantController.randomLastName);
|
||||||
router.get('/info', falukantController.getInfo);
|
router.get('/info', falukantController.getInfo);
|
||||||
router.get('/dashboard-widget', falukantController.getDashboardWidget);
|
|
||||||
router.get('/branches/types', falukantController.getBranchTypes);
|
router.get('/branches/types', falukantController.getBranchTypes);
|
||||||
router.get('/branches/:branch', falukantController.getBranch);
|
router.get('/branches/:branch', falukantController.getBranch);
|
||||||
router.get('/branches', falukantController.getBranches);
|
router.get('/branches', falukantController.getBranches);
|
||||||
@@ -29,7 +28,6 @@ router.get('/inventory/?:branchId', falukantController.getInventory);
|
|||||||
router.post('/sell/all', falukantController.sellAllProducts);
|
router.post('/sell/all', falukantController.sellAllProducts);
|
||||||
router.post('/sell', falukantController.sellProduct);
|
router.post('/sell', falukantController.sellProduct);
|
||||||
router.post('/moneyhistory', falukantController.moneyHistory);
|
router.post('/moneyhistory', falukantController.moneyHistory);
|
||||||
router.post('/moneyhistory/graph', falukantController.moneyHistoryGraph);
|
|
||||||
router.get('/storage/:branchId', falukantController.getStorage);
|
router.get('/storage/:branchId', falukantController.getStorage);
|
||||||
router.post('/storage', falukantController.buyStorage);
|
router.post('/storage', falukantController.buyStorage);
|
||||||
router.delete('/storage', falukantController.sellStorage);
|
router.delete('/storage', falukantController.sellStorage);
|
||||||
@@ -47,8 +45,6 @@ router.get('/family/children', falukantController.getChildren);
|
|||||||
router.post('/family/gift', falukantController.sendGift);
|
router.post('/family/gift', falukantController.sendGift);
|
||||||
router.get('/family', falukantController.getFamily);
|
router.get('/family', falukantController.getFamily);
|
||||||
router.get('/nobility/titels', falukantController.getTitlesOfNobility);
|
router.get('/nobility/titels', falukantController.getTitlesOfNobility);
|
||||||
router.get('/reputation/actions', falukantController.getReputationActions);
|
|
||||||
router.post('/reputation/actions', falukantController.executeReputationAction);
|
|
||||||
router.get('/houses/types', falukantController.getHouseTypes);
|
router.get('/houses/types', falukantController.getHouseTypes);
|
||||||
router.get('/houses/buyable', falukantController.getBuyableHouses);
|
router.get('/houses/buyable', falukantController.getBuyableHouses);
|
||||||
router.get('/houses', falukantController.getUserHouse);
|
router.get('/houses', falukantController.getUserHouse);
|
||||||
@@ -60,11 +56,6 @@ router.post('/party', falukantController.createParty);
|
|||||||
router.get('/party', falukantController.getParties);
|
router.get('/party', falukantController.getParties);
|
||||||
router.get('/family/notbaptised', falukantController.getNotBaptisedChildren);
|
router.get('/family/notbaptised', falukantController.getNotBaptisedChildren);
|
||||||
router.post('/church/baptise', falukantController.baptise);
|
router.post('/church/baptise', falukantController.baptise);
|
||||||
router.get('/church/overview', falukantController.getChurchOverview);
|
|
||||||
router.get('/church/positions/available', falukantController.getAvailableChurchPositions);
|
|
||||||
router.get('/church/applications/supervised', falukantController.getSupervisedApplications);
|
|
||||||
router.post('/church/positions/apply', falukantController.applyForChurchPosition);
|
|
||||||
router.post('/church/applications/decide', falukantController.decideOnChurchApplication);
|
|
||||||
router.get('/education', falukantController.getEducation);
|
router.get('/education', falukantController.getEducation);
|
||||||
router.post('/education', falukantController.sendToSchool);
|
router.post('/education', falukantController.sendToSchool);
|
||||||
router.get('/bank/overview', falukantController.getBankOverview);
|
router.get('/bank/overview', falukantController.getBankOverview);
|
||||||
@@ -76,14 +67,13 @@ router.get('/health', falukantController.getHealth);
|
|||||||
router.post('/health', falukantController.healthActivity);
|
router.post('/health', falukantController.healthActivity);
|
||||||
router.get('/politics/overview', falukantController.getPoliticsOverview);
|
router.get('/politics/overview', falukantController.getPoliticsOverview);
|
||||||
router.get('/politics/open', falukantController.getOpenPolitics);
|
router.get('/politics/open', falukantController.getOpenPolitics);
|
||||||
router.post('/politics/open', falukantController.applyForElections);
|
|
||||||
router.get('/politics/elections', falukantController.getElections);
|
router.get('/politics/elections', falukantController.getElections);
|
||||||
router.post('/politics/elections', falukantController.vote);
|
router.post('/politics/elections', falukantController.vote);
|
||||||
|
router.get('/politics/open', falukantController.getOpenPolitics);
|
||||||
|
router.post('/politics/open', falukantController.applyForElections);
|
||||||
router.get('/cities', falukantController.getRegions);
|
router.get('/cities', falukantController.getRegions);
|
||||||
router.get('/products/price-in-region', falukantController.getProductPriceInRegion);
|
router.get('/products/price-in-region', falukantController.getProductPriceInRegion);
|
||||||
router.get('/products/prices-in-region', falukantController.getAllProductPricesInRegion);
|
|
||||||
router.get('/products/prices-in-cities', falukantController.getProductPricesInCities);
|
router.get('/products/prices-in-cities', falukantController.getProductPricesInCities);
|
||||||
router.post('/products/prices-in-cities-batch', falukantController.getProductPricesInCitiesBatch);
|
|
||||||
router.get('/branches/:branchId/taxes', falukantController.getBranchTaxes);
|
router.get('/branches/:branchId/taxes', falukantController.getBranchTaxes);
|
||||||
router.get('/vehicles/types', falukantController.getVehicleTypes);
|
router.get('/vehicles/types', falukantController.getVehicleTypes);
|
||||||
router.post('/vehicles', falukantController.buyVehicles);
|
router.post('/vehicles', falukantController.buyVehicles);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -210,14 +210,6 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
branchId: {
|
|
||||||
immediate: false,
|
|
||||||
handler() {
|
|
||||||
this.loadDirector();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
async mounted() {
|
async mounted() {
|
||||||
await this.loadDirector();
|
await this.loadDirector();
|
||||||
},
|
},
|
||||||
@@ -264,17 +256,11 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
speedLabel(value) {
|
speedLabel(value) {
|
||||||
if (value == null) return this.$t('falukant.branch.transport.speed.unknown') || '—';
|
const key = value == null ? 'unknown' : String(value);
|
||||||
if (typeof value === 'object') {
|
|
||||||
const k = value.tr ?? value.id ?? 'unknown';
|
|
||||||
const tKey = `falukant.branch.transport.speed.${k}`;
|
|
||||||
const t = this.$t(tKey);
|
|
||||||
return (t && t !== tKey) ? t : String(k);
|
|
||||||
}
|
|
||||||
const key = String(value);
|
|
||||||
const tKey = `falukant.branch.transport.speed.${key}`;
|
const tKey = `falukant.branch.transport.speed.${key}`;
|
||||||
const translated = this.$t(tKey);
|
const translated = this.$t(tKey);
|
||||||
return (!translated || translated === tKey) ? key : translated;
|
if (!translated || translated === tKey) return value;
|
||||||
|
return translated;
|
||||||
},
|
},
|
||||||
|
|
||||||
openNewDirectorDialog() {
|
openNewDirectorDialog() {
|
||||||
|
|||||||
@@ -251,6 +251,13 @@
|
|||||||
return new Date(a.eta).getTime() - new Date(b.eta).getTime();
|
return new Date(a.eta).getTime() - new Date(b.eta).getTime();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
speedLabel(value) {
|
||||||
|
const key = value == null ? 'unknown' : String(value);
|
||||||
|
const tKey = `falukant.branch.transport.speed.${key}`;
|
||||||
|
const translated = this.$t(tKey);
|
||||||
|
if (!translated || translated === tKey) return value;
|
||||||
|
return translated;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
await this.loadInventory();
|
await this.loadInventory();
|
||||||
@@ -267,19 +274,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
speedLabel(value) {
|
|
||||||
if (value == null) return this.$t('falukant.branch.transport.speed.unknown') || '—';
|
|
||||||
if (typeof value === 'object') {
|
|
||||||
const k = value.tr ?? value.id ?? 'unknown';
|
|
||||||
const tKey = `falukant.branch.transport.speed.${k}`;
|
|
||||||
const t = this.$t(tKey);
|
|
||||||
return (t && t !== tKey) ? t : String(k);
|
|
||||||
}
|
|
||||||
const key = String(value);
|
|
||||||
const tKey = `falukant.branch.transport.speed.${key}`;
|
|
||||||
const translated = this.$t(tKey);
|
|
||||||
return (!translated || translated === tKey) ? key : translated;
|
|
||||||
},
|
|
||||||
async loadInventory() {
|
async loadInventory() {
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.get(`/api/falukant/inventory/${this.branchId}`);
|
const response = await apiClient.get(`/api/falukant/inventory/${this.branchId}`);
|
||||||
@@ -293,24 +287,25 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async loadPricesForInventory() {
|
async loadPricesForInventory() {
|
||||||
if (this.inventory.length === 0) return;
|
for (const item of this.inventory) {
|
||||||
const currentRegionId = this.inventory[0]?.region?.id ?? null;
|
const itemKey = `${item.region.id}-${item.product.id}-${item.quality}`;
|
||||||
const items = this.inventory.map(item => ({
|
if (this.loadingPrices.has(itemKey)) continue;
|
||||||
productId: item.product.id,
|
this.loadingPrices.add(itemKey);
|
||||||
currentPrice: item.product.sellCost || 0
|
try {
|
||||||
}));
|
// Aktueller Preis basierend auf sellCost
|
||||||
try {
|
const currentPrice = item.product.sellCost || 0;
|
||||||
const { data } = await apiClient.post('/api/falukant/products/prices-in-cities-batch', {
|
const { data } = await apiClient.get('/api/falukant/products/prices-in-cities', {
|
||||||
currentRegionId,
|
params: {
|
||||||
items
|
productId: item.product.id,
|
||||||
});
|
currentPrice: currentPrice
|
||||||
for (const item of this.inventory) {
|
}
|
||||||
item.betterPrices = data && data[item.product.id] ? data[item.product.id] : [];
|
});
|
||||||
}
|
this.$set(item, 'betterPrices', data || []);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading prices for inventory:', error);
|
console.error(`Error loading prices for item ${itemKey}:`, error);
|
||||||
for (const item of this.inventory) {
|
this.$set(item, 'betterPrices', []);
|
||||||
item.betterPrices = [];
|
} finally {
|
||||||
|
this.loadingPrices.delete(itemKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -114,21 +114,11 @@
|
|||||||
},
|
},
|
||||||
"overview": {
|
"overview": {
|
||||||
"title": "Falukant - Übersicht",
|
"title": "Falukant - Übersicht",
|
||||||
"heirSelection": {
|
|
||||||
"title": "Erben-Auswahl",
|
|
||||||
"description": "Dein bisheriger Charakter ist nicht mehr verfügbar. Wähle einen Erben aus der Liste, um mit diesem weiterzuspielen.",
|
|
||||||
"loading": "Lade mögliche Erben…",
|
|
||||||
"noHeirs": "Keine Erben verfügbar.",
|
|
||||||
"select": "Als Spielcharakter wählen",
|
|
||||||
"error": "Fehler beim Auswählen des Erben."
|
|
||||||
},
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"title": "Persönliches",
|
"title": "Persönliches",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"money": "Vermögen",
|
"money": "Vermögen",
|
||||||
"age": "Alter",
|
"age": "Alter",
|
||||||
"years": "Jahre",
|
|
||||||
"days": "Tage",
|
|
||||||
"mainbranch": "Heimatstadt",
|
"mainbranch": "Heimatstadt",
|
||||||
"nobleTitle": "Stand"
|
"nobleTitle": "Stand"
|
||||||
},
|
},
|
||||||
@@ -317,9 +307,6 @@
|
|||||||
"current": "Laufende Produktionen",
|
"current": "Laufende Produktionen",
|
||||||
"product": "Produkt",
|
"product": "Produkt",
|
||||||
"remainingTime": "Verbleibende Zeit (Sekunden)",
|
"remainingTime": "Verbleibende Zeit (Sekunden)",
|
||||||
"status": "Status",
|
|
||||||
"sleep": "Pausiert",
|
|
||||||
"active": "Aktiv",
|
|
||||||
"noProductions": "Keine laufenden Produktionen."
|
"noProductions": "Keine laufenden Produktionen."
|
||||||
},
|
},
|
||||||
"columns": {
|
"columns": {
|
||||||
@@ -591,23 +578,6 @@
|
|||||||
"time": "Zeit",
|
"time": "Zeit",
|
||||||
"prev": "Zurück",
|
"prev": "Zurück",
|
||||||
"next": "Weiter",
|
"next": "Weiter",
|
||||||
"graph": {
|
|
||||||
"open": "Verlauf anzeigen",
|
|
||||||
"title": "Geldentwicklung",
|
|
||||||
"close": "Schließen",
|
|
||||||
"loading": "Lade Verlauf...",
|
|
||||||
"noData": "Für den gewählten Zeitraum liegen keine Buchungen vor.",
|
|
||||||
"yesterday": "Gestern",
|
|
||||||
"range": {
|
|
||||||
"label": "Zeitraum",
|
|
||||||
"today": "Heute",
|
|
||||||
"24h": "Letzte 24 Stunden",
|
|
||||||
"week": "Letzte Woche",
|
|
||||||
"month": "Letzter Monat",
|
|
||||||
"year": "Letztes Jahr",
|
|
||||||
"all": "Gesamter Verlauf"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"activities": {
|
"activities": {
|
||||||
"Product sale": "Produkte verkauft",
|
"Product sale": "Produkte verkauft",
|
||||||
"Production cost": "Produktionskosten",
|
"Production cost": "Produktionskosten",
|
||||||
@@ -678,7 +648,6 @@
|
|||||||
"happy": "Glücklich",
|
"happy": "Glücklich",
|
||||||
"sad": "Traurig",
|
"sad": "Traurig",
|
||||||
"angry": "Wütend",
|
"angry": "Wütend",
|
||||||
"calm": "Ruhig",
|
|
||||||
"nervous": "Nervös",
|
"nervous": "Nervös",
|
||||||
"excited": "Aufgeregt",
|
"excited": "Aufgeregt",
|
||||||
"bored": "Gelangweilt",
|
"bored": "Gelangweilt",
|
||||||
@@ -774,34 +743,7 @@
|
|||||||
"reputation": {
|
"reputation": {
|
||||||
"title": "Reputation",
|
"title": "Reputation",
|
||||||
"overview": {
|
"overview": {
|
||||||
"title": "Übersicht",
|
"title": "Übersicht"
|
||||||
"current": "Aktuelle Reputation"
|
|
||||||
},
|
|
||||||
"actions": {
|
|
||||||
"title": "Reputations-Aktionen",
|
|
||||||
"description": "Du kannst verschiedene Aktionen durchführen, um deine Reputation zu verbessern.",
|
|
||||||
"none": "Keine Reputations-Aktionen verfügbar.",
|
|
||||||
"action": "Aktion",
|
|
||||||
"cost": "Kosten",
|
|
||||||
"gain": "Gewinn",
|
|
||||||
"timesUsed": "Verwendet",
|
|
||||||
"execute": "Ausführen",
|
|
||||||
"running": "Läuft...",
|
|
||||||
"dailyLimit": "Tägliches Limit: {remaining} von {cap} Aktionen übrig",
|
|
||||||
"cooldown": "Cooldown: Noch {minutes} Minuten",
|
|
||||||
"type": {
|
|
||||||
"soup_kitchen": "Suppenküche",
|
|
||||||
"library_donation": "Bibliotheksspende",
|
|
||||||
"scholarships": "Stipendien",
|
|
||||||
"church_hospice": "Kirchenhospiz",
|
|
||||||
"school_funding": "Schulfinanzierung",
|
|
||||||
"orphanage_build": "Waisenhaus bauen",
|
|
||||||
"bridge_build": "Brücke bauen",
|
|
||||||
"hospital_donation": "Krankenhausspende",
|
|
||||||
"patronage": "Mäzenatentum",
|
|
||||||
"statue_build": "Statue errichten",
|
|
||||||
"well_build": "Brunnen bauen"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"party": {
|
"party": {
|
||||||
"title": "Feste",
|
"title": "Feste",
|
||||||
@@ -852,53 +794,6 @@
|
|||||||
},
|
},
|
||||||
"church": {
|
"church": {
|
||||||
"title": "Kirche",
|
"title": "Kirche",
|
||||||
"tabs": {
|
|
||||||
"current": "Aktuelle Positionen",
|
|
||||||
"available": "Verfügbare Positionen",
|
|
||||||
"applications": "Bewerbungen"
|
|
||||||
},
|
|
||||||
"current": {
|
|
||||||
"office": "Amt",
|
|
||||||
"region": "Region",
|
|
||||||
"holder": "Inhaber",
|
|
||||||
"supervisor": "Vorgesetzter",
|
|
||||||
"none": "Keine aktuellen Positionen vorhanden."
|
|
||||||
},
|
|
||||||
"available": {
|
|
||||||
"office": "Amt",
|
|
||||||
"region": "Region",
|
|
||||||
"supervisor": "Vorgesetzter",
|
|
||||||
"seats": "Verfügbare Plätze",
|
|
||||||
"action": "Aktion",
|
|
||||||
"apply": "Bewerben",
|
|
||||||
"applySuccess": "Bewerbung erfolgreich eingereicht.",
|
|
||||||
"applyError": "Fehler beim Einreichen der Bewerbung.",
|
|
||||||
"none": "Keine verfügbaren Positionen."
|
|
||||||
},
|
|
||||||
"applications": {
|
|
||||||
"office": "Amt",
|
|
||||||
"region": "Region",
|
|
||||||
"applicant": "Bewerber",
|
|
||||||
"date": "Datum",
|
|
||||||
"action": "Aktion",
|
|
||||||
"approve": "Annehmen",
|
|
||||||
"reject": "Ablehnen",
|
|
||||||
"approveSuccess": "Bewerbung angenommen.",
|
|
||||||
"rejectSuccess": "Bewerbung abgelehnt.",
|
|
||||||
"decideError": "Fehler bei der Entscheidung.",
|
|
||||||
"none": "Keine Bewerbungen vorhanden."
|
|
||||||
},
|
|
||||||
"offices": {
|
|
||||||
"lay-preacher": "Laienprediger",
|
|
||||||
"village-priest": "Dorfgeistlicher",
|
|
||||||
"parish-priest": "Pfarrer",
|
|
||||||
"dean": "Dekan",
|
|
||||||
"archdeacon": "Erzdiakon",
|
|
||||||
"bishop": "Bischof",
|
|
||||||
"archbishop": "Erzbischof",
|
|
||||||
"cardinal": "Kardinal",
|
|
||||||
"pope": "Papst"
|
|
||||||
},
|
|
||||||
"baptism": {
|
"baptism": {
|
||||||
"title": "Taufen",
|
"title": "Taufen",
|
||||||
"table": {
|
"table": {
|
||||||
@@ -1000,12 +895,7 @@
|
|||||||
"drunkOfLife": "Trunk des Lebens",
|
"drunkOfLife": "Trunk des Lebens",
|
||||||
"barber": "Barbier"
|
"barber": "Barbier"
|
||||||
},
|
},
|
||||||
"choose": "Bitte auswählen",
|
"choose": "Bitte auswählen"
|
||||||
"errors": {
|
|
||||||
"tooClose": "Du kannst nicht so oft Maßnahmen durchführen.",
|
|
||||||
"generic": "Ein Fehler ist aufgetreten."
|
|
||||||
},
|
|
||||||
"nextMeasureAt": "Nächste Maßnahme ab"
|
|
||||||
},
|
},
|
||||||
"politics": {
|
"politics": {
|
||||||
"title": "Politik",
|
"title": "Politik",
|
||||||
@@ -1029,13 +919,9 @@
|
|||||||
"region": "Region",
|
"region": "Region",
|
||||||
"date": "Datum",
|
"date": "Datum",
|
||||||
"candidacy": "Kandidatur",
|
"candidacy": "Kandidatur",
|
||||||
"candidacyWithAge": "Kandidatur (ab 16 Jahren)",
|
|
||||||
"none": "Keine offenen Positionen.",
|
"none": "Keine offenen Positionen.",
|
||||||
"apply": "Für ausgewählte Positionen kandidieren",
|
"apply": "Für ausgewählte Positionen kandidieren"
|
||||||
"minAgeHint": "Kandidatur erst ab 16 Jahren möglich.",
|
|
||||||
"ageRequirement": "Für alle politischen Ämter gilt: Kandidatur erst ab 16 Jahren."
|
|
||||||
},
|
},
|
||||||
"too_young": "Dein Charakter ist noch zu jung. Eine Bewerbung ist erst ab 16 Jahren möglich.",
|
|
||||||
"upcoming": {
|
"upcoming": {
|
||||||
"office": "Amt",
|
"office": "Amt",
|
||||||
"region": "Region",
|
"region": "Region",
|
||||||
|
|||||||
@@ -93,27 +93,6 @@
|
|||||||
"children": "Children",
|
"children": "Children",
|
||||||
"children_unbaptised": "Unbaptised children"
|
"children_unbaptised": "Unbaptised children"
|
||||||
},
|
},
|
||||||
"overview": {
|
|
||||||
"title": "Falukant - Overview",
|
|
||||||
"heirSelection": {
|
|
||||||
"title": "Heir Selection",
|
|
||||||
"description": "Your previous character is no longer available. Choose an heir from the list to continue playing.",
|
|
||||||
"loading": "Loading potential heirs…",
|
|
||||||
"noHeirs": "No heirs available.",
|
|
||||||
"select": "Select as play character",
|
|
||||||
"error": "Error selecting heir."
|
|
||||||
},
|
|
||||||
"metadata": {
|
|
||||||
"title": "Personal",
|
|
||||||
"name": "Name",
|
|
||||||
"money": "Wealth",
|
|
||||||
"age": "Age",
|
|
||||||
"years": "Years",
|
|
||||||
"days": "Days",
|
|
||||||
"mainbranch": "Home city",
|
|
||||||
"nobleTitle": "Title"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"health": {
|
"health": {
|
||||||
"amazing": "Amazing",
|
"amazing": "Amazing",
|
||||||
"good": "Good",
|
"good": "Good",
|
||||||
@@ -132,23 +111,6 @@
|
|||||||
"time": "Time",
|
"time": "Time",
|
||||||
"prev": "Previous",
|
"prev": "Previous",
|
||||||
"next": "Next",
|
"next": "Next",
|
||||||
"graph": {
|
|
||||||
"open": "Show graph",
|
|
||||||
"title": "Money over time",
|
|
||||||
"close": "Close",
|
|
||||||
"loading": "Loading history...",
|
|
||||||
"noData": "No entries for the selected period.",
|
|
||||||
"yesterday": "Yesterday",
|
|
||||||
"range": {
|
|
||||||
"label": "Range",
|
|
||||||
"today": "Today",
|
|
||||||
"24h": "Last 24 hours",
|
|
||||||
"week": "Last week",
|
|
||||||
"month": "Last month",
|
|
||||||
"year": "Last year",
|
|
||||||
"all": "All history"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"activities": {
|
"activities": {
|
||||||
"Product sale": "Product sale",
|
"Product sale": "Product sale",
|
||||||
"Production cost": "Production cost",
|
"Production cost": "Production cost",
|
||||||
@@ -203,29 +165,6 @@
|
|||||||
"income": "Income",
|
"income": "Income",
|
||||||
"incomeUpdated": "Salary has been successfully updated."
|
"incomeUpdated": "Salary has been successfully updated."
|
||||||
},
|
},
|
||||||
"production": {
|
|
||||||
"title": "Production",
|
|
||||||
"info": "Details about production in the branch.",
|
|
||||||
"selectProduct": "Select product",
|
|
||||||
"quantity": "Quantity",
|
|
||||||
"storageAvailable": "Free storage",
|
|
||||||
"cost": "Cost",
|
|
||||||
"duration": "Duration",
|
|
||||||
"revenue": "Revenue",
|
|
||||||
"start": "Start production",
|
|
||||||
"success": "Production started successfully!",
|
|
||||||
"error": "Error starting production.",
|
|
||||||
"minutes": "Minutes",
|
|
||||||
"ending": "Ending:",
|
|
||||||
"time": "Time",
|
|
||||||
"current": "Running productions",
|
|
||||||
"product": "Product",
|
|
||||||
"remainingTime": "Remaining time (seconds)",
|
|
||||||
"status": "Status",
|
|
||||||
"sleep": "Paused",
|
|
||||||
"active": "Active",
|
|
||||||
"noProductions": "No running productions."
|
|
||||||
},
|
|
||||||
"vehicles": {
|
"vehicles": {
|
||||||
"cargo_cart": "Cargo cart",
|
"cargo_cart": "Cargo cart",
|
||||||
"ox_cart": "Ox cart",
|
"ox_cart": "Ox cart",
|
||||||
@@ -258,86 +197,7 @@
|
|||||||
},
|
},
|
||||||
"nobility": {
|
"nobility": {
|
||||||
"cooldown": "You can only advance again on {date}."
|
"cooldown": "You can only advance again on {date}."
|
||||||
},
|
},
|
||||||
"mood": {
|
|
||||||
"happy": "Happy",
|
|
||||||
"sad": "Sad",
|
|
||||||
"angry": "Angry",
|
|
||||||
"calm": "Calm",
|
|
||||||
"nervous": "Nervous",
|
|
||||||
"excited": "Excited",
|
|
||||||
"bored": "Bored",
|
|
||||||
"fearful": "Fearful",
|
|
||||||
"confident": "Confident",
|
|
||||||
"curious": "Curious",
|
|
||||||
"hopeful": "Hopeful",
|
|
||||||
"frustrated": "Frustrated",
|
|
||||||
"lonely": "Lonely",
|
|
||||||
"grateful": "Grateful",
|
|
||||||
"jealous": "Jealous",
|
|
||||||
"guilty": "Guilty",
|
|
||||||
"apathetic": "Apathetic",
|
|
||||||
"relieved": "Relieved",
|
|
||||||
"proud": "Proud",
|
|
||||||
"ashamed": "Ashamed"
|
|
||||||
},
|
|
||||||
"character": {
|
|
||||||
"brave": "Brave",
|
|
||||||
"kind": "Kind",
|
|
||||||
"greedy": "Greedy",
|
|
||||||
"wise": "Wise",
|
|
||||||
"loyal": "Loyal",
|
|
||||||
"cunning": "Cunning",
|
|
||||||
"generous": "Generous",
|
|
||||||
"arrogant": "Arrogant",
|
|
||||||
"honest": "Honest",
|
|
||||||
"ambitious": "Ambitious",
|
|
||||||
"patient": "Patient",
|
|
||||||
"impatient": "Impatient",
|
|
||||||
"selfish": "Selfish",
|
|
||||||
"charismatic": "Charismatic",
|
|
||||||
"empathetic": "Empathetic",
|
|
||||||
"timid": "Timid",
|
|
||||||
"stubborn": "Stubborn",
|
|
||||||
"resourceful": "Resourceful",
|
|
||||||
"reckless": "Reckless",
|
|
||||||
"disciplined": "Disciplined",
|
|
||||||
"optimistic": "Optimistic",
|
|
||||||
"pessimistic": "Pessimistic",
|
|
||||||
"manipulative": "Manipulative",
|
|
||||||
"independent": "Independent",
|
|
||||||
"dependent": "Dependent",
|
|
||||||
"adventurous": "Adventurous",
|
|
||||||
"humble": "Humble",
|
|
||||||
"vengeful": "Vengeful",
|
|
||||||
"pragmatic": "Pragmatic",
|
|
||||||
"idealistic": "Idealistic"
|
|
||||||
},
|
|
||||||
"healthview": {
|
|
||||||
"title": "Health",
|
|
||||||
"age": "Age",
|
|
||||||
"status": "Health Status",
|
|
||||||
"measuresTaken": "Measures Taken",
|
|
||||||
"measure": "Measure",
|
|
||||||
"date": "Date",
|
|
||||||
"cost": "Cost",
|
|
||||||
"success": "Success",
|
|
||||||
"selectMeasure": "Select Measure",
|
|
||||||
"perform": "Perform",
|
|
||||||
"measures": {
|
|
||||||
"pill": "Pill",
|
|
||||||
"doctor": "Doctor Visit",
|
|
||||||
"witch": "Witch",
|
|
||||||
"drunkOfLife": "Elixir of Life",
|
|
||||||
"barber": "Barber"
|
|
||||||
},
|
|
||||||
"choose": "Please select",
|
|
||||||
"errors": {
|
|
||||||
"tooClose": "You cannot perform measures so often.",
|
|
||||||
"generic": "An error occurred."
|
|
||||||
},
|
|
||||||
"nextMeasureAt": "Next measure from"
|
|
||||||
},
|
|
||||||
"branchProduction": {
|
"branchProduction": {
|
||||||
"storageAvailable": "Free storage"
|
"storageAvailable": "Free storage"
|
||||||
},
|
},
|
||||||
@@ -363,13 +223,9 @@
|
|||||||
"region": "Region",
|
"region": "Region",
|
||||||
"date": "Date",
|
"date": "Date",
|
||||||
"candidacy": "Candidacy",
|
"candidacy": "Candidacy",
|
||||||
"candidacyWithAge": "Candidacy (from age 16)",
|
|
||||||
"none": "No open positions.",
|
"none": "No open positions.",
|
||||||
"apply": "Apply for selected positions",
|
"apply": "Apply for selected positions"
|
||||||
"minAgeHint": "Candidacy is only possible from age 16.",
|
|
||||||
"ageRequirement": "All political offices require candidates to be at least 16 years old."
|
|
||||||
},
|
},
|
||||||
"too_young": "Your character is too young. Applications are only possible from age 16.",
|
|
||||||
"upcoming": {
|
"upcoming": {
|
||||||
"office": "Office",
|
"office": "Office",
|
||||||
"region": "Region",
|
"region": "Region",
|
||||||
@@ -466,143 +322,6 @@
|
|||||||
"success": "The gift has been given.",
|
"success": "The gift has been given.",
|
||||||
"nextGiftAt": "Next gift from"
|
"nextGiftAt": "Next gift from"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"church": {
|
|
||||||
"title": "Church",
|
|
||||||
"tabs": {
|
|
||||||
"current": "Current Positions",
|
|
||||||
"available": "Available Positions",
|
|
||||||
"applications": "Applications"
|
|
||||||
},
|
|
||||||
"current": {
|
|
||||||
"office": "Office",
|
|
||||||
"region": "Region",
|
|
||||||
"holder": "Holder",
|
|
||||||
"supervisor": "Supervisor",
|
|
||||||
"none": "No current positions available."
|
|
||||||
},
|
|
||||||
"available": {
|
|
||||||
"office": "Office",
|
|
||||||
"region": "Region",
|
|
||||||
"supervisor": "Supervisor",
|
|
||||||
"seats": "Available Seats",
|
|
||||||
"action": "Action",
|
|
||||||
"apply": "Apply",
|
|
||||||
"applySuccess": "Application submitted successfully.",
|
|
||||||
"applyError": "Error submitting application.",
|
|
||||||
"none": "No available positions."
|
|
||||||
},
|
|
||||||
"applications": {
|
|
||||||
"office": "Office",
|
|
||||||
"region": "Region",
|
|
||||||
"applicant": "Applicant",
|
|
||||||
"date": "Date",
|
|
||||||
"action": "Action",
|
|
||||||
"approve": "Approve",
|
|
||||||
"reject": "Reject",
|
|
||||||
"approveSuccess": "Application approved.",
|
|
||||||
"rejectSuccess": "Application rejected.",
|
|
||||||
"decideError": "Error making decision.",
|
|
||||||
"none": "No applications available."
|
|
||||||
},
|
|
||||||
"offices": {
|
|
||||||
"lay-preacher": "Lay Preacher",
|
|
||||||
"village-priest": "Village Priest",
|
|
||||||
"parish-priest": "Parish Priest",
|
|
||||||
"dean": "Dean",
|
|
||||||
"archdeacon": "Archdeacon",
|
|
||||||
"bishop": "Bishop",
|
|
||||||
"archbishop": "Archbishop",
|
|
||||||
"cardinal": "Cardinal",
|
|
||||||
"pope": "Pope"
|
|
||||||
},
|
|
||||||
"baptism": {
|
|
||||||
"title": "Baptism",
|
|
||||||
"table": {
|
|
||||||
"name": "First Name",
|
|
||||||
"gender": "Gender",
|
|
||||||
"age": "Age",
|
|
||||||
"baptise": "Baptize (50)",
|
|
||||||
"newName": "Suggest Name"
|
|
||||||
},
|
|
||||||
"gender": {
|
|
||||||
"male": "Boy",
|
|
||||||
"female": "Girl"
|
|
||||||
},
|
|
||||||
"success": "The child has been baptized.",
|
|
||||||
"error": "The child could not be baptized."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"reputation": {
|
|
||||||
"title": "Reputation",
|
|
||||||
"overview": {
|
|
||||||
"title": "Overview",
|
|
||||||
"current": "Current Reputation"
|
|
||||||
},
|
|
||||||
"actions": {
|
|
||||||
"title": "Reputation Actions",
|
|
||||||
"description": "You can perform various actions to improve your reputation.",
|
|
||||||
"none": "No reputation actions available.",
|
|
||||||
"action": "Action",
|
|
||||||
"cost": "Cost",
|
|
||||||
"gain": "Gain",
|
|
||||||
"timesUsed": "Used",
|
|
||||||
"execute": "Execute",
|
|
||||||
"running": "Running...",
|
|
||||||
"dailyLimit": "Daily limit: {remaining} of {cap} actions remaining",
|
|
||||||
"cooldown": "Cooldown: {minutes} minutes remaining",
|
|
||||||
"type": {
|
|
||||||
"soup_kitchen": "Soup Kitchen",
|
|
||||||
"library_donation": "Library Donation",
|
|
||||||
"scholarships": "Scholarships",
|
|
||||||
"church_hospice": "Church Hospice",
|
|
||||||
"school_funding": "School Funding",
|
|
||||||
"orphanage_build": "Build Orphanage",
|
|
||||||
"bridge_build": "Build Bridge",
|
|
||||||
"hospital_donation": "Hospital Donation",
|
|
||||||
"patronage": "Patronage",
|
|
||||||
"statue_build": "Build Statue",
|
|
||||||
"well_build": "Build Well"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"party": {
|
|
||||||
"title": "Parties",
|
|
||||||
"totalCost": "Total Cost",
|
|
||||||
"order": "Order Party",
|
|
||||||
"inProgress": "Parties in Preparation",
|
|
||||||
"completed": "Completed Parties",
|
|
||||||
"newpartyview": {
|
|
||||||
"open": "Create New Party",
|
|
||||||
"close": "Hide New Party",
|
|
||||||
"type": "Party Type"
|
|
||||||
},
|
|
||||||
"music": {
|
|
||||||
"label": "Music",
|
|
||||||
"none": "No Music",
|
|
||||||
"bard": "A Bard",
|
|
||||||
"villageBand": "A Village Band",
|
|
||||||
"chamberOrchestra": "A Chamber Orchestra",
|
|
||||||
"symphonyOrchestra": "A Symphony Orchestra",
|
|
||||||
"symphonyOrchestraWithChorusAndSolists": "A Symphony Orchestra with Chorus and Soloists"
|
|
||||||
},
|
|
||||||
"banquette": {
|
|
||||||
"label": "Food",
|
|
||||||
"bread": "Bread",
|
|
||||||
"roastWithBeer": "Roast with Beer",
|
|
||||||
"poultryWithVegetablesAndWine": "Poultry with Vegetables and Wine",
|
|
||||||
"extensiveBuffet": "Festive Meal"
|
|
||||||
},
|
|
||||||
"servants": {
|
|
||||||
"label": "One servant per ",
|
|
||||||
"perPersons": " persons"
|
|
||||||
},
|
|
||||||
"esteemedInvites": {
|
|
||||||
"label": "Invited Estates"
|
|
||||||
},
|
|
||||||
"type": "Party Type",
|
|
||||||
"cost": "Cost",
|
|
||||||
"date": "Date"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -360,7 +360,6 @@ export default {
|
|||||||
vehicles: [],
|
vehicles: [],
|
||||||
activeTab: 'production',
|
activeTab: 'production',
|
||||||
productPricesCache: {}, // Cache für regionale Preise: { productId: price }
|
productPricesCache: {}, // Cache für regionale Preise: { productId: price }
|
||||||
productPricesCacheRegionId: null, // regionId, für die der Cache gültig ist
|
|
||||||
tabs: [
|
tabs: [
|
||||||
{ value: 'production', label: 'falukant.branch.tabs.production' },
|
{ value: 'production', label: 'falukant.branch.tabs.production' },
|
||||||
{ value: 'inventory', label: 'falukant.branch.tabs.inventory' },
|
{ value: 'inventory', label: 'falukant.branch.tabs.inventory' },
|
||||||
@@ -570,46 +569,30 @@ export default {
|
|||||||
async loadProductPricesForCurrentBranch() {
|
async loadProductPricesForCurrentBranch() {
|
||||||
if (!this.selectedBranch || !this.selectedBranch.regionId) {
|
if (!this.selectedBranch || !this.selectedBranch.regionId) {
|
||||||
this.productPricesCache = {};
|
this.productPricesCache = {};
|
||||||
this.productPricesCacheRegionId = null;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.productPricesCacheRegionId === this.selectedBranch.regionId && Object.keys(this.productPricesCache).length > 0) {
|
|
||||||
return;
|
// Lade Preise für alle Produkte in der aktuellen Region
|
||||||
}
|
const prices = {};
|
||||||
try {
|
for (const product of this.products) {
|
||||||
const { data } = await apiClient.get('/api/falukant/products/prices-in-region', {
|
try {
|
||||||
params: {
|
const { data } = await apiClient.get('/api/falukant/products/price-in-region', {
|
||||||
regionId: this.selectedBranch.regionId
|
params: {
|
||||||
}
|
productId: product.id,
|
||||||
});
|
regionId: this.selectedBranch.regionId
|
||||||
this.productPricesCache = data.prices || {};
|
}
|
||||||
this.productPricesCacheRegionId = this.selectedBranch.regionId;
|
});
|
||||||
} catch (error) {
|
prices[product.id] = data.price;
|
||||||
console.error(`Error loading product prices for region ${this.selectedBranch.regionId}:`, error);
|
} catch (error) {
|
||||||
// Fallback: Lade Preise einzeln (alte Methode)
|
console.error(`Error loading price for product ${product.id}:`, error);
|
||||||
console.warn('[BranchView] Falling back to individual product price requests');
|
// Fallback auf Standard-Berechnung
|
||||||
const prices = {};
|
const knowledgeFactor = product.knowledges?.[0]?.knowledge || 0;
|
||||||
for (const product of this.products) {
|
const maxPrice = product.sellCost;
|
||||||
try {
|
const minPrice = maxPrice * 0.6;
|
||||||
const { data } = await apiClient.get('/api/falukant/products/price-in-region', {
|
prices[product.id] = minPrice + (maxPrice - minPrice) * (knowledgeFactor / 100);
|
||||||
params: {
|
|
||||||
productId: product.id,
|
|
||||||
regionId: this.selectedBranch.regionId
|
|
||||||
}
|
|
||||||
});
|
|
||||||
prices[product.id] = data.price;
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Error loading price for product ${product.id}:`, err);
|
|
||||||
// Fallback auf Standard-Berechnung
|
|
||||||
const knowledgeFactor = product.knowledges?.[0]?.knowledge || 0;
|
|
||||||
const maxPrice = product.sellCost;
|
|
||||||
const minPrice = maxPrice * 0.6;
|
|
||||||
prices[product.id] = minPrice + (maxPrice - minPrice) * (knowledgeFactor / 100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.productPricesCache = prices;
|
|
||||||
this.productPricesCacheRegionId = this.selectedBranch?.regionId ?? null;
|
|
||||||
}
|
}
|
||||||
|
this.productPricesCache = prices;
|
||||||
},
|
},
|
||||||
|
|
||||||
formatPercent(value) {
|
formatPercent(value) {
|
||||||
@@ -721,17 +704,13 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
speedLabel(value) {
|
speedLabel(value) {
|
||||||
if (value == null) return this.$t('falukant.branch.transport.speed.unknown') || '—';
|
// Expect numeric speeds 1..4; provide localized labels as fallback to raw value
|
||||||
if (typeof value === 'object') {
|
const key = value == null ? 'unknown' : String(value);
|
||||||
const k = value.tr ?? value.id ?? 'unknown';
|
|
||||||
const tKey = `falukant.branch.transport.speed.${k}`;
|
|
||||||
const t = this.$t(tKey);
|
|
||||||
return (t && t !== tKey) ? t : String(k);
|
|
||||||
}
|
|
||||||
const key = String(value);
|
|
||||||
const tKey = `falukant.branch.transport.speed.${key}`;
|
const tKey = `falukant.branch.transport.speed.${key}`;
|
||||||
const translated = this.$t(tKey);
|
const translated = this.$t(tKey);
|
||||||
return (!translated || translated === tKey) ? key : translated;
|
// If translation returns the key (no translation found), fall back to the numeric value
|
||||||
|
if (!translated || translated === tKey) return value;
|
||||||
|
return translated;
|
||||||
},
|
},
|
||||||
|
|
||||||
transportModeLabel(mode) {
|
transportModeLabel(mode) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $t('falukant.family.spouse.mood') }}</td>
|
<td>{{ $t('falukant.family.spouse.mood') }}</td>
|
||||||
<td>{{ relationships[0].character2.mood?.tr ? $t(`falukant.mood.${relationships[0].character2.mood.tr}`) : '—' }}</td>
|
<td>{{ $t(`falukant.mood.${relationships[0].character2.mood.tr}`) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $t('falukant.family.spouse.status') }}</td>
|
<td>{{ $t('falukant.family.spouse.status') }}</td>
|
||||||
|
|||||||
@@ -9,12 +9,6 @@
|
|||||||
<button @click="fetchMoneyHistory(1)">{{ $t('falukant.moneyHistory.search') }}</button>
|
<button @click="fetchMoneyHistory(1)">{{ $t('falukant.moneyHistory.search') }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="graph-section">
|
|
||||||
<button @click="openGraphDialog">
|
|
||||||
{{ $t('falukant.moneyHistory.graph.open') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -48,21 +42,17 @@
|
|||||||
{{ $t('falukant.moneyHistory.next') }}
|
{{ $t('falukant.moneyHistory.next') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MoneyHistoryGraphDialog ref="graphDialog" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import StatusBar from '@/components/falukant/StatusBar.vue'
|
import StatusBar from '@/components/falukant/StatusBar.vue'
|
||||||
import MoneyHistoryGraphDialog from '@/dialogues/falukant/MoneyHistoryGraphDialog.vue'
|
|
||||||
import apiClient from '@/utils/axios.js';
|
import apiClient from '@/utils/axios.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MoneyHistoryView',
|
name: 'MoneyHistoryView',
|
||||||
components: {
|
components: {
|
||||||
StatusBar,
|
StatusBar,
|
||||||
MoneyHistoryGraphDialog,
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
locale() {
|
locale() {
|
||||||
@@ -107,9 +97,6 @@ export default {
|
|||||||
}
|
}
|
||||||
return translation !== key ? translation : activity;
|
return translation !== key ? translation : activity;
|
||||||
},
|
},
|
||||||
openGraphDialog() {
|
|
||||||
this.$refs.graphDialog.open();
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -119,10 +106,6 @@ export default {
|
|||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.graph-section {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="pos in currentPositions" :key="pos.id" :class="{ 'own-position': isOwnPosition(pos) }">
|
<tr v-for="pos in currentPositions" :key="pos.id">
|
||||||
<td>{{ $t(`falukant.politics.offices.${pos.officeType.name}`) }}</td>
|
<td>{{ $t(`falukant.politics.offices.${pos.officeType.name}`) }}</td>
|
||||||
<td>{{ pos.region.name }}</td>
|
<td>{{ pos.region.name }}</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -57,7 +57,6 @@
|
|||||||
|
|
||||||
<!-- OPEN Tab: hier zeigen wir 'openPolitics' -->
|
<!-- OPEN Tab: hier zeigen wir 'openPolitics' -->
|
||||||
<div v-else-if="activeTab === 'openPolitics'" class="tab-pane">
|
<div v-else-if="activeTab === 'openPolitics'" class="tab-pane">
|
||||||
<p class="politics-age-requirement">{{ $t('falukant.politics.open.ageRequirement') }}</p>
|
|
||||||
<div v-if="loading.openPolitics" class="loading">{{ $t('loading') }}</div>
|
<div v-if="loading.openPolitics" class="loading">{{ $t('loading') }}</div>
|
||||||
<div v-else class="table-scroll">
|
<div v-else class="table-scroll">
|
||||||
<table class="politics-table">
|
<table class="politics-table">
|
||||||
@@ -66,7 +65,7 @@
|
|||||||
<th>{{ $t('falukant.politics.open.office') }}</th>
|
<th>{{ $t('falukant.politics.open.office') }}</th>
|
||||||
<th>{{ $t('falukant.politics.open.region') }}</th>
|
<th>{{ $t('falukant.politics.open.region') }}</th>
|
||||||
<th>{{ $t('falukant.politics.open.date') }}</th>
|
<th>{{ $t('falukant.politics.open.date') }}</th>
|
||||||
<th>{{ $t('falukant.politics.open.candidacyWithAge') }}</th>
|
<th>{{ $t('falukant.politics.open.candidacy') }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -75,13 +74,13 @@
|
|||||||
<td>{{ e.region.name }}</td>
|
<td>{{ e.region.name }}</td>
|
||||||
<td>{{ formatDate(e.date) }}</td>
|
<td>{{ formatDate(e.date) }}</td>
|
||||||
<!-- Checkbox ganz am Ende -->
|
<!-- Checkbox ganz am Ende -->
|
||||||
<td :title="e.canApplyByAge === false ? $t('falukant.politics.open.minAgeHint') : null">
|
<td>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
:id="`apply-${e.id}`"
|
:id="`apply-${e.id}`"
|
||||||
v-model="selectedApplications"
|
v-model="selectedApplications"
|
||||||
:value="e.id"
|
:value="e.id"
|
||||||
:disabled="e.alreadyApplied || e.canApplyByAge === false"
|
:disabled="e.alreadyApplied"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -194,7 +193,6 @@ export default {
|
|||||||
elections: [],
|
elections: [],
|
||||||
selectedCandidates: {},
|
selectedCandidates: {},
|
||||||
selectedApplications: [],
|
selectedApplications: [],
|
||||||
ownCharacterId: null,
|
|
||||||
loading: {
|
loading: {
|
||||||
current: false,
|
current: false,
|
||||||
openPolitics: false,
|
openPolitics: false,
|
||||||
@@ -212,7 +210,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loadOwnCharacterId();
|
|
||||||
this.loadCurrentPositions();
|
this.loadCurrentPositions();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -232,12 +229,9 @@ export default {
|
|||||||
this.loading.current = true;
|
this.loading.current = true;
|
||||||
try {
|
try {
|
||||||
const { data } = await apiClient.get('/api/falukant/politics/overview');
|
const { data } = await apiClient.get('/api/falukant/politics/overview');
|
||||||
console.log('[PoliticsView] loadCurrentPositions - API response:', data);
|
|
||||||
console.log('[PoliticsView] loadCurrentPositions - ownCharacterId at load time:', this.ownCharacterId);
|
|
||||||
this.currentPositions = data;
|
this.currentPositions = data;
|
||||||
console.log('[PoliticsView] loadCurrentPositions - Loaded', data.length, 'positions');
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[PoliticsView] Error loading current positions', err);
|
console.error('Error loading current positions', err);
|
||||||
} finally {
|
} finally {
|
||||||
this.loading.current = false;
|
this.loading.current = false;
|
||||||
}
|
}
|
||||||
@@ -247,10 +241,10 @@ export default {
|
|||||||
this.loading.openPolitics = true;
|
this.loading.openPolitics = true;
|
||||||
try {
|
try {
|
||||||
const { data } = await apiClient.get('/api/falukant/politics/open');
|
const { data } = await apiClient.get('/api/falukant/politics/open');
|
||||||
this.openPolitics = Array.isArray(data) ? data : [];
|
this.openPolitics = data;
|
||||||
// Bereits beworbene Positionen vorselektieren, damit die Checkbox
|
// Bereits beworbene Positionen vorselektieren, damit die Checkbox
|
||||||
// sichtbar markiert bleibt.
|
// sichtbar markiert bleibt.
|
||||||
this.selectedApplications = this.openPolitics
|
this.selectedApplications = data
|
||||||
.filter(e => e.alreadyApplied)
|
.filter(e => e.alreadyApplied)
|
||||||
.map(e => e.id);
|
.map(e => e.id);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -336,44 +330,6 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async loadOwnCharacterId() {
|
|
||||||
try {
|
|
||||||
const { data } = await apiClient.get('/api/falukant/info');
|
|
||||||
console.log('[PoliticsView] loadOwnCharacterId - API response:', data);
|
|
||||||
console.log('[PoliticsView] loadOwnCharacterId - data.character:', data.character);
|
|
||||||
console.log('[PoliticsView] loadOwnCharacterId - data.character?.id:', data.character?.id);
|
|
||||||
if (data.character && data.character.id) {
|
|
||||||
this.ownCharacterId = data.character.id;
|
|
||||||
console.log('[PoliticsView] loadOwnCharacterId - Set ownCharacterId to:', this.ownCharacterId);
|
|
||||||
} else {
|
|
||||||
console.warn('[PoliticsView] loadOwnCharacterId - No character ID found in response', {
|
|
||||||
hasCharacter: !!data.character,
|
|
||||||
characterKeys: data.character ? Object.keys(data.character) : null,
|
|
||||||
characterId: data.character?.id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error('[PoliticsView] Error loading own character ID', err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
isOwnPosition(pos) {
|
|
||||||
console.log('[PoliticsView] isOwnPosition - Checking position:', {
|
|
||||||
posId: pos.id,
|
|
||||||
posCharacter: pos.character,
|
|
||||||
posCharacterId: pos.character?.id,
|
|
||||||
ownCharacterId: this.ownCharacterId,
|
|
||||||
match: pos.character?.id === this.ownCharacterId
|
|
||||||
});
|
|
||||||
if (!this.ownCharacterId || !pos.character) {
|
|
||||||
console.log('[PoliticsView] isOwnPosition - Returning false (missing ownCharacterId or pos.character)');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const isMatch = pos.character.id === this.ownCharacterId;
|
|
||||||
console.log('[PoliticsView] isOwnPosition - Result:', isMatch);
|
|
||||||
return isMatch;
|
|
||||||
},
|
|
||||||
|
|
||||||
async submitApplications() {
|
async submitApplications() {
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.post(
|
const response = await apiClient.post(
|
||||||
@@ -390,10 +346,6 @@ export default {
|
|||||||
.map(e => e.id);
|
.map(e => e.id);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error submitting applications', err);
|
console.error('Error submitting applications', err);
|
||||||
const msg = err?.response?.data?.error === 'too_young'
|
|
||||||
? this.$t('falukant.politics.too_young')
|
|
||||||
: (err?.response?.data?.error || err?.message || this.$t('falukant.politics.applyError'));
|
|
||||||
this.$root.$refs?.messageDialog?.open?.(msg, this.$t('falukant.politics.title'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -432,13 +384,6 @@ h2 {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.politics-age-requirement {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
margin: 0 0 10px 0;
|
|
||||||
font-size: 0.95em;
|
|
||||||
color: #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-scroll {
|
.table-scroll {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@@ -466,11 +411,6 @@ h2 {
|
|||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.politics-table tbody tr.own-position {
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading {
|
.loading {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
|||||||
Reference in New Issue
Block a user