Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
42 changes: 42 additions & 0 deletions app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,52 @@
<NuxtPage />
</NuxtLayout>
<ModalStack />
<div
v-if="showExternalUrlWarning"
class="fixed flex flex-row gap-x-2 right-0 bottom-0 m-2 px-2 py-2 z-50 text-right bg-red-700/90 rounded-lg"
>
<div class="flex flex-col">
<span class="text-sm text-zinc-200 font-bold font-display">{{
$t("errors.externalUrl.title")
}}</span>
<span class="text-xs text-red-400">{{
$t("errors.externalUrl.subtitle")
}}</span>
</div>
<button class="text-red-200" @click="() => hideExternalURL()">
<XMarkIcon class="size-5" />
</button>
</div>
</template>

<script setup lang="ts">
import { XMarkIcon } from "@heroicons/vue/24/outline";

await updateUser();

const user = useUser();
const apiDetails = await $dropFetch("/api/v1");

const showExternalUrlWarning = ref(false);
function checkExternalUrl() {
if (!import.meta.client) return;
const realOrigin = window.location.origin.trim();
const chosenOrigin = apiDetails.external.trim();
const ignore = window.localStorage.getItem("ignoreExternalUrl");
if (ignore && ignore == "true") return;
showExternalUrlWarning.value = !(realOrigin == chosenOrigin);
}

function hideExternalURL() {
window.localStorage.setItem("ignoreExternalUrl", "true");
showExternalUrlWarning.value = false;
}

if (user.value?.admin) {
onMounted(() => {
checkExternalUrl();
});
}
</script>

<style scoped>
Expand Down
148 changes: 148 additions & 0 deletions components/Modal/CreateCompany.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<template>
<ModalTemplate v-model="open">
<template #default>
<div>
<h3 class="text-lg font-medium leading-6 text-white">
{{ $t("library.admin.metadata.companies.modals.createTitle") }}
</h3>
<p class="mt-1 text-zinc-400 text-sm">
{{ $t("library.admin.metadata.companies.modals.createDescription") }}
</p>
</div>
<div class="mt-2">
<form class="space-y-4" @submit.prevent="() => createCompany()">
<div>
<label
for="name"
class="block text-sm/6 font-medium text-zinc-100"
>{{
$t("library.admin.metadata.companies.modals.createFieldName")
}}</label
>
<div class="mt-2">
<input
id="name"
v-model="companyName"
type="text"
name="name"
:placeholder="
$t(
'library.admin.metadata.companies.modals.createFieldNamePlaceholder',
)
"
class="block w-full rounded-md bg-zinc-800 px-3 py-1.5 text-base text-zinc-100 outline outline-1 -outline-offset-1 outline-zinc-700 placeholder:text-zinc-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-blue-600 sm:text-sm/6"
/>
</div>
</div>
<div>
<label
for="description"
class="block text-sm/6 font-medium text-zinc-100"
>{{
$t(
"library.admin.metadata.companies.modals.createFieldDescription",
)
}}</label
>
<div class="mt-2">
<input
id="description"
v-model="companyDescription"
type="text"
name="description"
:placeholder="
$t(
'library.admin.metadata.companies.modals.createFieldDescriptionPlaceholder',
)
"
class="block w-full rounded-md bg-zinc-800 px-3 py-1.5 text-base text-zinc-100 outline outline-1 -outline-offset-1 outline-zinc-700 placeholder:text-zinc-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-blue-600 sm:text-sm/6"
/>
</div>
</div>
<div>
<label
for="website"
class="block text-sm/6 font-medium text-zinc-100"
>{{
$t("library.admin.metadata.companies.modals.createFieldWebsite")
}}</label
>
<div class="mt-2">
<input
id="website"
v-model="companyWebsite"
type="text"
name="website"
:placeholder="
$t(
'library.admin.metadata.companies.modals.createFieldWebsitePlaceholder',
)
"
class="block w-full rounded-md bg-zinc-800 px-3 py-1.5 text-base text-zinc-100 outline outline-1 -outline-offset-1 outline-zinc-700 placeholder:text-zinc-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-blue-600 sm:text-sm/6"
/>
</div>
</div>

<button class="hidden" type="submit" />
</form>
</div>
</template>

<template #buttons="{ close }">
<LoadingButton
:loading="loading"
:disabled="!companyValid"
class="w-full sm:w-fit"
@click="() => createCompany()"
>
{{ $t("common.create") }}
</LoadingButton>
<button
ref="cancelButtonRef"
type="button"
class="mt-3 inline-flex w-full justify-center rounded-md bg-zinc-800 px-3 py-2 text-sm font-semibold text-zinc-100 shadow-sm ring-1 ring-inset ring-zinc-800 hover:bg-zinc-900 sm:mt-0 sm:w-auto"
@click="() => close()"
>
{{ $t("cancel") }}
</button>
</template>
</ModalTemplate>
</template>

<script setup lang="ts">
import type { CompanyModel } from "~/prisma/client/models";

const open = defineModel<boolean>({ required: true });

const emit = defineEmits<{
created: [company: CompanyModel];
}>();

const companyName = ref("");
const companyDescription = ref("");
const companyWebsite = ref("");

const loading = ref(false);
const companyValid = computed(
() => companyName.value && companyDescription.value,
);
async function createCompany() {
loading.value = true;
try {
const newCompany = await $dropFetch("/api/v1/admin/company", {
method: "POST",
body: {
name: companyName.value,
description: companyDescription.value,
website: companyWebsite.value,
},
failTitle: "Failed to create new company",
});
open.value = false;
emit("created", newCompany);
} finally {
/* empty */
}
loading.value = false;
}
</script>
2 changes: 1 addition & 1 deletion components/StoreView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@
<div
v-if="games?.length ?? 0 > 0"
ref="product-grid"
class="relative lg:col-span-4 grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6 gap-4"
class="relative lg:col-span-4 grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-4 xl:grid-cols-6 2xl:grid-cols-7 gap-4"
>
<!-- Your content -->
<GamePanel
Expand Down
23 changes: 20 additions & 3 deletions i18n/locales/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@
"desc": "Drop encountered an error while updating the version: {error}",
"title": "There an error while updating the version order"
}
},
"externalUrl": {
"title": "Accessing over different EXTERNAL_URL. Please check the docs.",
"subtitle": "This message is only visible to admins."
}
},
"footer": {
Expand Down Expand Up @@ -329,15 +333,26 @@
"noDescription": "(no description)",
"published": "Published",
"uploadBanner": "Upload banner",
"uploadIcon": "Upload icon"
"uploadIcon": "Upload icon",
"descriptionPlaceholder": "{'<'}description{'>'}",
"websitePlaceholder": "{'<'}website{'>'}"
},
"modals": {
"nameDescription": "Edit the company's name. Used to match to new game imports.",
"nameTitle": "Edit company name",
"shortDeckDescription": "Edit the company's description. Doesn't affect long (markdown) description.",
"shortDeckTitle": "Edit company description",
"websiteDescription": "Edit the company's website. Note: this will be a link, and won't have redirect protection.",
"websiteTitle": "Edit company website"
"websiteTitle": "Edit company website",

"createTitle": "Create a company",
"createDescription": "Create a company to further organize your games.",
"createFieldName": "Company Name",
"createFieldNamePlaceholder": "My New Company...",
"createFieldDescription": "Company Description",
"createFieldDescriptionPlaceholder": "A small indie studio that...",
"createFieldWebsite": "Company Website",
"createFieldWebsitePlaceholder": "https://example.com/"
},
"noCompanies": "No companies",
"noGames": "No games",
Expand Down Expand Up @@ -499,7 +514,9 @@
"images": "Game Images",
"lookAt": "Check it out",
"noDevelopers": "No developers",
"noGame": "no game",
"noGame": "NO GAME",
"noFeatured": "NO FEATURED GAMES",
"openFeatured": "Star games in Admin Library {arrow}",
"noImages": "No images",
"noPublishers": "No publishers.",
"noTags": "No tags",
Expand Down
1 change: 1 addition & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export default defineNuxtConfig({

scheduledTasks: {
"0 * * * *": ["dailyTasks"],
"*/30 * * * *": ["downloadCleanup"],
},

storage: {
Expand Down
11 changes: 7 additions & 4 deletions pages/admin/metadata/companies/[id]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
{{ company.mName }}
<button @click="() => editName()">
<PencilIcon
class="transition duration-200 opacity-0 group-hover/name:opacity-100 size-8"
class="transition duration-200 xl:opacity-0 group-hover/name:opacity-100 size-8"
/>
</button>
</h1>
Expand All @@ -43,17 +43,20 @@
}}
<button @click="() => editShortDescription()">
<PencilIcon
class="transition duration-200 opacity-0 group-hover/description:opacity-100 size-5"
class="transition duration-200 xl:opacity-0 group-hover/description:opacity-100 size-5"
/>
</button>
</p>
<p
class="group/website mt-1 text-zinc-500 inline-flex items-center gap-x-3"
>
{{ company.mWebsite }}
{{
company.mWebsite ||
$t("library.admin.metadata.companies.editor.websitePlaceholder")
}}
<button @click="() => editWebsite()">
<PencilIcon
class="transition duration-200 opacity-0 group-hover/website:opacity-100 size-4"
class="transition duration-200 xl:opacity-0 group-hover/website:opacity-100 size-4"
/>
</button>
</p>
Expand Down
29 changes: 16 additions & 13 deletions pages/admin/metadata/companies/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,12 @@
</p>
</div>
<div class="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
<NuxtLink
to="/admin/library/sources"
<button
class="block rounded-md bg-blue-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm transition-all duration-200 hover:bg-blue-500 hover:scale-105 hover:shadow-lg hover:shadow-blue-500/25 active:scale-95 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
@click="() => (createCompanyOpen = true)"
>
<i18n-t
keypath="library.admin.sources.link"
tag="span"
scope="global"
>
<template #arrow>
<span aria-hidden="true">{{ $t("chars.arrow") }}</span>
</template>
</i18n-t>
</NuxtLink>
{{ $t("common.create") }}
</button>
</div>
</div>
<div class="mt-2 grid grid-cols-1">
Expand Down Expand Up @@ -105,6 +97,10 @@
{{ $t("library.admin.metadata.companies.noCompanies") }}
</p>
</ul>
<ModalCreateCompany
v-model="createCompanyOpen"
@created="(company) => createCompany(company)"
/>
</div>
</template>

Expand All @@ -122,9 +118,12 @@ useHead({
title: t("library.admin.metadata.companies.title"),
});

const createCompanyOpen = ref(false);

const searchQuery = ref("");

const companies = ref(await $dropFetch("/api/v1/admin/company"));
const rawCompanies = await $dropFetch("/api/v1/admin/company");
const companies = ref(rawCompanies);

const filteredCompanies = computed(() =>
companies.value.filter((e: CompanyModel) => {
Expand All @@ -147,4 +146,8 @@ async function deleteCompany(id: string) {
const index = companies.value.findIndex((e) => e.id === id);
companies.value.splice(index, 1);
}

function createCompany(company: (typeof companies.value)[number]) {
companies.value.push(company);
}
</script>
Loading