diff --git a/.vscode/settings.json b/.vscode/settings.json index d4d338f6dc..7522198819 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -29,5 +29,7 @@ }, "[rust]": { "editor.defaultFormatter": "rust-lang.rust-analyzer" - } + }, + "css.lint.unknownAtRules": "ignore", + "scss.lint.unknownAtRules": "ignore" } diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue index 6b1b964a1a..041209b551 100644 --- a/apps/app-frontend/src/App.vue +++ b/apps/app-frontend/src/App.vue @@ -1,5 +1,11 @@ + + diff --git a/apps/app-frontend/src/config.ts b/apps/app-frontend/src/config.ts new file mode 100644 index 0000000000..bc98d33109 --- /dev/null +++ b/apps/app-frontend/src/config.ts @@ -0,0 +1,7 @@ +// src/config.ts +export const config = { + siteUrl: import.meta.env.VITE_SITE_URL, + stripePublishableKey: + import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY || + 'pk_test_51JbFxJJygY5LJFfKV50mnXzz3YLvBVe2Gd1jn7ljWAkaBlRz3VQdxN9mXcPSrFbSqxwAb0svte9yhnsmm7qHfcWn00R611Ce7b', +} diff --git a/apps/app-frontend/src/locales/en-US/index.json b/apps/app-frontend/src/locales/en-US/index.json index f7f558ae65..d93726e438 100644 --- a/apps/app-frontend/src/locales/en-US/index.json +++ b/apps/app-frontend/src/locales/en-US/index.json @@ -185,6 +185,9 @@ "app.modal.update-to-play.update-required-description": { "message": "An update is required to play {name}. Please update to the latest version to launch the game." }, + "app.server-settings.failed-to-load-server": { + "message": "Failed to load server settings" + }, "app.settings.developer-mode-enabled": { "message": "Developer mode enabled." }, @@ -598,5 +601,11 @@ }, "search.filter.locked.server-loader.title": { "message": "Loader is provided by the server" + }, + "servers.busy.installing": { + "message": "Server is installing" + }, + "servers.busy.syncing-content": { + "message": "Content sync in progress" } } diff --git a/apps/app-frontend/src/pages/Servers.vue b/apps/app-frontend/src/pages/Servers.vue new file mode 100644 index 0000000000..5e6e1b427a --- /dev/null +++ b/apps/app-frontend/src/pages/Servers.vue @@ -0,0 +1,27 @@ + + + diff --git a/apps/app-frontend/src/pages/hosting/manage/Backups.vue b/apps/app-frontend/src/pages/hosting/manage/Backups.vue new file mode 100644 index 0000000000..59f00d03ea --- /dev/null +++ b/apps/app-frontend/src/pages/hosting/manage/Backups.vue @@ -0,0 +1,9 @@ + + + diff --git a/apps/app-frontend/src/pages/hosting/manage/Content.vue b/apps/app-frontend/src/pages/hosting/manage/Content.vue new file mode 100644 index 0000000000..02742246de --- /dev/null +++ b/apps/app-frontend/src/pages/hosting/manage/Content.vue @@ -0,0 +1,7 @@ + + + diff --git a/apps/app-frontend/src/pages/hosting/manage/Files.vue b/apps/app-frontend/src/pages/hosting/manage/Files.vue new file mode 100644 index 0000000000..532c9b1392 --- /dev/null +++ b/apps/app-frontend/src/pages/hosting/manage/Files.vue @@ -0,0 +1,7 @@ + + + diff --git a/apps/app-frontend/src/pages/hosting/manage/Index.vue b/apps/app-frontend/src/pages/hosting/manage/Index.vue new file mode 100644 index 0000000000..fc1015e7a0 --- /dev/null +++ b/apps/app-frontend/src/pages/hosting/manage/Index.vue @@ -0,0 +1,346 @@ + + + diff --git a/apps/app-frontend/src/pages/hosting/manage/index.js b/apps/app-frontend/src/pages/hosting/manage/index.js new file mode 100644 index 0000000000..127c22afce --- /dev/null +++ b/apps/app-frontend/src/pages/hosting/manage/index.js @@ -0,0 +1,6 @@ +import Backups from './Backups.vue' +import Content from './Content.vue' +import Files from './Files.vue' +import Index from './Index.vue' + +export { Backups, Content, Files, Index } diff --git a/apps/app-frontend/src/pages/index.js b/apps/app-frontend/src/pages/index.js index d08a3fbeb6..5a4294937a 100644 --- a/apps/app-frontend/src/pages/index.js +++ b/apps/app-frontend/src/pages/index.js @@ -1,6 +1,7 @@ import Browse from './Browse.vue' import Index from './Index.vue' +import Servers from './Servers.vue' import Skins from './Skins.vue' import Worlds from './Worlds.vue' -export { Browse, Index, Skins, Worlds } +export { Browse, Index, Servers, Skins, Worlds } diff --git a/apps/app-frontend/src/routes.js b/apps/app-frontend/src/routes.js index 18c6df173c..2748853d58 100644 --- a/apps/app-frontend/src/routes.js +++ b/apps/app-frontend/src/routes.js @@ -1,7 +1,7 @@ -import { ServersManagePageIndex } from '@modrinth/ui' import { createRouter, createWebHistory } from 'vue-router' import * as Pages from '@/pages' +import * as Hosting from '@/pages/hosting/manage' import * as Instance from '@/pages/instance' import * as Library from '@/pages/library' import * as Project from '@/pages/project' @@ -31,11 +31,41 @@ export default new createRouter({ { path: '/hosting/manage/', name: 'Servers', - component: ServersManagePageIndex, + component: Pages.Servers, meta: { breadcrumb: [{ name: 'Servers' }], }, }, + { + path: '/hosting/manage/:id', + name: 'ServerManage', + component: Hosting.Index, + children: [ + { + path: '', + redirect: (to) => { + const rawId = Array.isArray(to.params.id) ? to.params.id[0] : to.params.id + if (!rawId) return '/hosting/manage' + return `/hosting/manage/${encodeURIComponent(rawId)}/content` + }, + }, + { + path: 'content', + name: 'ServerManageContent', + component: Hosting.Content, + }, + { + path: 'files', + name: 'ServerManageFiles', + component: Hosting.Files, + }, + { + path: 'backups', + name: 'ServerManageBackups', + component: Hosting.Backups, + }, + ], + }, { path: '/browse/:projectType', name: 'Discover content', diff --git a/apps/app-frontend/tsconfig.app.json b/apps/app-frontend/tsconfig.app.json index 8d5b455fe5..f723e2026f 100644 --- a/apps/app-frontend/tsconfig.app.json +++ b/apps/app-frontend/tsconfig.app.json @@ -16,6 +16,8 @@ "strict": true, + "types": ["vite/client"], + "paths": { "@/*": ["./src/*"] } diff --git a/apps/app/tauri.conf.json b/apps/app/tauri.conf.json index 986347dc30..bc06fa6405 100644 --- a/apps/app/tauri.conf.json +++ b/apps/app/tauri.conf.json @@ -87,12 +87,12 @@ "capabilities": ["ads", "core", "plugins"], "csp": { "default-src": "'self' customprotocol: asset:", - "connect-src": "ipc: http://ipc.localhost https://modrinth.com https://*.modrinth.com https://*.posthog.com https://*.sentry.io https://api.mclo.gs http://textures.minecraft.net https://textures.minecraft.net 'self' data: blob:", + "connect-src": "ipc: http://ipc.localhost https://modrinth.com https://*.modrinth.com https://*.posthog.com https://posthog.modrinth.com https://*.sentry.io https://api.mclo.gs http://textures.minecraft.net https://textures.minecraft.net https://js.stripe.com https://*.stripe.com wss://*.stripe.com wss://*.nodes.modrinth.com 'self' data: blob:", "font-src": ["https://cdn-raw.modrinth.com/fonts/"], "img-src": "https: 'unsafe-inline' 'self' asset: http://asset.localhost http://textures.minecraft.net blob: data:", "style-src": "'unsafe-inline' 'self'", - "script-src": "https://*.posthog.com https://tally.so/widgets/embed.js 'self'", - "frame-src": "https://www.youtube.com https://www.youtube-nocookie.com https://discord.com https://tally.so/popup/ 'self'", + "script-src": "https://*.posthog.com https://posthog.modrinth.com https://js.stripe.com https://tally.so/widgets/embed.js 'self'", + "frame-src": "https://www.youtube.com https://www.youtube-nocookie.com https://discord.com https://tally.so/popup/ https://js.stripe.com https://hooks.stripe.com 'self'", "media-src": "https://*.githubusercontent.com" } } diff --git a/apps/frontend/src/assets/styles/components.scss b/apps/frontend/src/assets/styles/components.scss index 9ac5ec5b91..b04291d4c7 100644 --- a/apps/frontend/src/assets/styles/components.scss +++ b/apps/frontend/src/assets/styles/components.scss @@ -841,6 +841,23 @@ button { opacity: 0.5; box-shadow: none; flex-shrink: 0; + user-select: none; + } + + .text-input-wrapper__after { + display: flex; + color: var(--color-text); + padding: 0.5rem 1rem 0.5rem 0; + font-weight: var(--font-weight-medium); + min-height: 36px; + box-sizing: border-box; + width: fit-content; + align-items: center; + filter: grayscale(50%); + opacity: 0.5; + box-shadow: none; + flex-shrink: 0; + user-select: none; } input, diff --git a/apps/frontend/src/assets/styles/global.scss b/apps/frontend/src/assets/styles/global.scss index 305b14442b..917240e78d 100644 --- a/apps/frontend/src/assets/styles/global.scss +++ b/apps/frontend/src/assets/styles/global.scss @@ -456,9 +456,9 @@ kbd { font-size: 0.85em !important; } -@import '~/assets/styles/layout.scss'; -@import '~/assets/styles/utils.scss'; -@import '~/assets/styles/components.scss'; +@import './layout.scss'; +@import './utils.scss'; +@import './components.scss'; // OMORPHIA FIXES .card { diff --git a/apps/frontend/src/components/ui/servers/SaveBanner.vue b/apps/frontend/src/components/ui/servers/SaveBanner.vue index 092ca3b603..a43e4dd1f1 100644 --- a/apps/frontend/src/components/ui/servers/SaveBanner.vue +++ b/apps/frontend/src/components/ui/servers/SaveBanner.vue @@ -1,37 +1,5 @@ - - - + diff --git a/apps/frontend/src/locales/en-US/index.json b/apps/frontend/src/locales/en-US/index.json index 6fbe35c465..3e1ca2bb57 100644 --- a/apps/frontend/src/locales/en-US/index.json +++ b/apps/frontend/src/locales/en-US/index.json @@ -1301,60 +1301,6 @@ "hosting-marketing.why.your-favorite-mods.description": { "message": "Choose between Vanilla, Fabric, Forge, Quilt and NeoForge. If it's on Modrinth, it can run on your server." }, - "hosting.loader.failed-to-change-version": { - "message": "Failed to change modpack version" - }, - "hosting.loader.failed-to-load-versions": { - "message": "Failed to load versions" - }, - "hosting.loader.failed-to-reinstall": { - "message": "Failed to reinstall modpack" - }, - "hosting.loader.failed-to-repair": { - "message": "Failed to repair server" - }, - "hosting.loader.failed-to-reset-to-onboarding": { - "message": "Failed to reset server to onboarding" - }, - "hosting.loader.failed-to-save-settings": { - "message": "Failed to save installation settings" - }, - "hosting.loader.failed-to-unlink": { - "message": "Failed to unlink modpack" - }, - "hosting.loader.loader-version": { - "message": "{loader, select, null {Loader} other {{loader}}} version" - }, - "hosting.loader.repair-started-text": { - "message": "Your server installation has been repaired." - }, - "hosting.loader.repair-started-title": { - "message": "Repair completed" - }, - "hosting.loader.reset-server": { - "message": "Reset server" - }, - "hosting.loader.reset-server-description": { - "message": "Removes all data on your server, including your worlds, mods, and configuration files. Backups will remain and can be restored." - }, - "hosting.loader.reset-to-onboarding-button": { - "message": "Reset to onboarding" - }, - "hosting.loader.reset-to-onboarding-modal-description": { - "message": "This will send the server back into onboarding so setup can be completed again. Are you sure you want to continue?" - }, - "hosting.loader.reset-to-onboarding-modal-title": { - "message": "Reset to onboarding" - }, - "hosting.loader.reset-to-onboarding-success-description": { - "message": "The server has been returned to the onboarding flow." - }, - "hosting.loader.reset-to-onboarding-success-title": { - "message": "Server reset to onboarding" - }, - "hosting.loader.support-options-title": { - "message": "Support options" - }, "hosting.plan.out-of-stock": { "message": "Out of stock" }, @@ -3336,7 +3282,7 @@ "message": "Error resubscribing" }, "settings.billing.pyro.resubscribe.request-submitted.text": { - "message": "If the server is currently suspended, it may take up to 10 minutes for another charge attempt to be made." + "message": "If the server is currently cancelled, it may take 10-15 minutes to set up the server." }, "settings.billing.pyro.resubscribe.request-submitted.title": { "message": "Resubscription request submitted" diff --git a/apps/frontend/src/pages/admin/billing/[id].vue b/apps/frontend/src/pages/admin/billing/[id].vue index 98fafd5514..7549d7a004 100644 --- a/apps/frontend/src/pages/admin/billing/[id].vue +++ b/apps/frontend/src/pages/admin/billing/[id].vue @@ -519,7 +519,7 @@ async function modifyCharge() { }) addNotification({ title: 'Modifications made', - text: 'If the server is currently suspended, it may take up to 10 minutes for another charge attempt to be made.', + text: 'If the server is currently cancelled, it may take up to 10 minutes for another charge attempt to be made.', type: 'success', }) await refreshCharges() diff --git a/apps/frontend/src/pages/hosting/manage/[id].vue b/apps/frontend/src/pages/hosting/manage/[id].vue index be76662c72..abc00180c8 100644 --- a/apps/frontend/src/pages/hosting/manage/[id].vue +++ b/apps/frontend/src/pages/hosting/manage/[id].vue @@ -1185,7 +1185,8 @@ const handleInstallationResult = async (data: Archon.Websocket.v0.WSInstallation } const updateStats = (currentStats: Stats['current']) => { - isConnected.value = true + if (!isMounted.value) return + if (!isConnected.value) isConnected.value = true stats.value = { current: currentStats, past: { ...stats.value.current }, diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options.vue b/apps/frontend/src/pages/hosting/manage/[id]/options.vue index 9d4697de05..6fa28b857f 100644 --- a/apps/frontend/src/pages/hosting/manage/[id]/options.vue +++ b/apps/frontend/src/pages/hosting/manage/[id]/options.vue @@ -5,18 +5,13 @@ diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/advanced.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/advanced.vue new file mode 100644 index 0000000000..b730006fff --- /dev/null +++ b/apps/frontend/src/pages/hosting/manage/[id]/options/advanced.vue @@ -0,0 +1,7 @@ + + + diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/billing.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/billing.vue index db707f8a1e..6e470aaafc 100644 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/billing.vue +++ b/apps/frontend/src/pages/hosting/manage/[id]/options/billing.vue @@ -1,12 +1,7 @@ - - + + diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/index.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/index.vue index 09d45c96bc..311bee0a9c 100644 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/index.vue +++ b/apps/frontend/src/pages/hosting/manage/[id]/options/index.vue @@ -1,335 +1,7 @@ - - + + diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/info.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/info.vue deleted file mode 100644 index 35f89ad0ba..0000000000 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/info.vue +++ /dev/null @@ -1,154 +0,0 @@ - - - diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/loader.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/loader.vue index d68397c2f6..e3a54224ea 100644 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/loader.vue +++ b/apps/frontend/src/pages/hosting/manage/[id]/options/loader.vue @@ -1,806 +1,16 @@ - - + + diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/network.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/network.vue index f9fd5f60eb..a63867e288 100644 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/network.vue +++ b/apps/frontend/src/pages/hosting/manage/[id]/options/network.vue @@ -1,507 +1,7 @@ - - + + diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/preferences.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/preferences.vue deleted file mode 100644 index d3c84bf5b0..0000000000 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/preferences.vue +++ /dev/null @@ -1,113 +0,0 @@ - - - diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/properties.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/properties.vue index ae73daf967..48c1fb8a6d 100644 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/properties.vue +++ b/apps/frontend/src/pages/hosting/manage/[id]/options/properties.vue @@ -1,292 +1,7 @@ - - + + diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/startup.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/startup.vue deleted file mode 100644 index d8fd8c9859..0000000000 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/startup.vue +++ /dev/null @@ -1,287 +0,0 @@ - - - diff --git a/apps/frontend/src/pages/hosting/manage/index.vue b/apps/frontend/src/pages/hosting/manage/index.vue index 0767051ab9..0cd0a74a32 100644 --- a/apps/frontend/src/pages/hosting/manage/index.vue +++ b/apps/frontend/src/pages/hosting/manage/index.vue @@ -20,5 +20,6 @@ const generatedState = useGeneratedState() :stripe-publishable-key="config.public.stripePublishableKey" :site-url="config.public.siteUrl" :products="generatedState.products || []" + class="max-w-[1280px] py-0" /> diff --git a/apps/frontend/src/pages/settings/billing/index.vue b/apps/frontend/src/pages/settings/billing/index.vue index 3c5578042f..0c6df65c7c 100644 --- a/apps/frontend/src/pages/settings/billing/index.vue +++ b/apps/frontend/src/pages/settings/billing/index.vue @@ -1,5 +1,6 @@ + + diff --git a/packages/ui/src/components/billing/ServersGuestPlanModal.vue b/packages/ui/src/components/billing/ServersGuestPlanModal.vue new file mode 100644 index 0000000000..820a8b9ed1 --- /dev/null +++ b/packages/ui/src/components/billing/ServersGuestPlanModal.vue @@ -0,0 +1,169 @@ + + + diff --git a/packages/ui/src/components/billing/ServersPurchase0Plan.vue b/packages/ui/src/components/billing/ServersPurchase0Plan.vue index 88fa441d4d..cec037c849 100644 --- a/packages/ui/src/components/billing/ServersPurchase0Plan.vue +++ b/packages/ui/src/components/billing/ServersPurchase0Plan.vue @@ -1,13 +1,15 @@ diff --git a/packages/ui/src/components/billing/ServersPurchase1Region.vue b/packages/ui/src/components/billing/ServersPurchase1Region.vue index f81b3602d1..3e72a22d40 100644 --- a/packages/ui/src/components/billing/ServersPurchase1Region.vue +++ b/packages/ui/src/components/billing/ServersPurchase1Region.vue @@ -30,7 +30,7 @@ const props = defineProps<{ availableProducts: Labrinth.Billing.Internal.Product[] }>() -const loading = ref(true) +const loading = ref(false) const checkingCustomStock = ref(false) const selectedPlan = defineModel('plan') const selectedRegion = defineModel('region') @@ -214,12 +214,11 @@ async function updateStock() { onMounted(() => { // auto select region with lowest ping loading.value = true - bestPing.value = - props.pings.length > 0 - ? props.pings.reduce((acc, cur) => { - return acc.ping < cur.ping ? acc : cur - })?.region - : undefined + bestPing.value = props.pings.sort((a, b) => { + if (a.ping <= 0) return 1 + if (b.ping <= 0) return -1 + return a.ping - b.ping + })[0]?.region selectedRegion.value = undefined selectedRam.value = minRam.value checkingCustomStock.value = true diff --git a/packages/ui/src/components/billing/ServersPurchase3Review.vue b/packages/ui/src/components/billing/ServersPurchase3Review.vue index bcd83a5269..bfe6096c8d 100644 --- a/packages/ui/src/components/billing/ServersPurchase3Review.vue +++ b/packages/ui/src/components/billing/ServersPurchase3Review.vue @@ -179,7 +179,7 @@ function setInterval(newInterval: ServerBillingInterval) { -
+
No payment required. Your downgrade will apply at the end of the current billing period.
diff --git a/packages/ui/src/components/billing/index.ts b/packages/ui/src/components/billing/index.ts index f2ef22353b..4475573997 100644 --- a/packages/ui/src/components/billing/index.ts +++ b/packages/ui/src/components/billing/index.ts @@ -1,5 +1,7 @@ export { default as AddPaymentMethodModal } from './AddPaymentMethodModal.vue' export { default as ModrinthServersPurchaseModal } from './ModrinthServersPurchaseModal.vue' export { default as PurchaseModal } from './PurchaseModal.vue' +export { default as ResubscribeModal } from './ResubscribeModal.vue' +export { default as ServersGuestPlanModal } from './ServersGuestPlanModal.vue' export { default as ServersSpecs } from './ServersSpecs.vue' export { default as ServersUpgradeModalWrapper } from './ServersUpgradeModalWrapper.vue' diff --git a/packages/ui/src/components/modal/TabbedModal.vue b/packages/ui/src/components/modal/TabbedModal.vue index 2955e24792..eb2b63f038 100644 --- a/packages/ui/src/components/modal/TabbedModal.vue +++ b/packages/ui/src/components/modal/TabbedModal.vue @@ -1,6 +1,7 @@ + + diff --git a/packages/ui/src/components/servers/ServerListing.vue b/packages/ui/src/components/servers/ServerListing.vue index fe8dd4f4be..c52e8af693 100644 --- a/packages/ui/src/components/servers/ServerListing.vue +++ b/packages/ui/src/components/servers/ServerListing.vue @@ -1,108 +1,223 @@ diff --git a/packages/ui/src/layouts/shared/server-settings/index.ts b/packages/ui/src/layouts/shared/server-settings/index.ts new file mode 100644 index 0000000000..5f1ecde43b --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/index.ts @@ -0,0 +1,3 @@ +export * from './pages' +export * from './providers' +export * from './tabs' diff --git a/packages/ui/src/layouts/shared/server-settings/pages/advanced.vue b/packages/ui/src/layouts/shared/server-settings/pages/advanced.vue new file mode 100644 index 0000000000..2f44f8f30b --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/advanced.vue @@ -0,0 +1,391 @@ + + + + + diff --git a/packages/ui/src/layouts/shared/server-settings/pages/general.vue b/packages/ui/src/layouts/shared/server-settings/pages/general.vue new file mode 100644 index 0000000000..c3a86842a4 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/general.vue @@ -0,0 +1,426 @@ + + + diff --git a/packages/ui/src/layouts/shared/server-settings/pages/index.ts b/packages/ui/src/layouts/shared/server-settings/pages/index.ts new file mode 100644 index 0000000000..58ee8b39d3 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/index.ts @@ -0,0 +1,5 @@ +export { default as ServerSettingsAdvancedPage } from './advanced.vue' +export { default as ServerSettingsGeneralPage } from './general.vue' +export { default as ServerSettingsInstallationPage } from './installation.vue' +export { default as ServerSettingsNetworkPage } from './network.vue' +export { default as ServerSettingsPropertiesPage } from './properties.vue' diff --git a/packages/ui/src/layouts/shared/server-settings/pages/installation.vue b/packages/ui/src/layouts/shared/server-settings/pages/installation.vue new file mode 100644 index 0000000000..ea8ac8b096 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/installation.vue @@ -0,0 +1,808 @@ + + + diff --git a/packages/ui/src/layouts/shared/server-settings/pages/network.vue b/packages/ui/src/layouts/shared/server-settings/pages/network.vue new file mode 100644 index 0000000000..27a49f2ed6 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/network.vue @@ -0,0 +1,438 @@ + + + diff --git a/packages/ui/src/layouts/shared/server-settings/pages/properties.vue b/packages/ui/src/layouts/shared/server-settings/pages/properties.vue new file mode 100644 index 0000000000..1e77179214 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/properties.vue @@ -0,0 +1,526 @@ + + + diff --git a/packages/ui/src/layouts/shared/server-settings/providers/index.ts b/packages/ui/src/layouts/shared/server-settings/providers/index.ts new file mode 100644 index 0000000000..5b5bed990a --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/providers/index.ts @@ -0,0 +1 @@ +export * from './server-settings' diff --git a/packages/ui/src/layouts/shared/server-settings/providers/server-settings.ts b/packages/ui/src/layouts/shared/server-settings/providers/server-settings.ts new file mode 100644 index 0000000000..e5bb553ada --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/providers/server-settings.ts @@ -0,0 +1,21 @@ +import type { Ref } from 'vue' + +import { createContext } from '#ui/providers/create-context' + +export interface ServerSettingsBrowseModpacksArgs { + serverId: string + worldId: string | null + from: 'reset-server' +} + +export interface ServerSettingsContext { + isApp: Ref + currentUserId: Ref + currentUserRole: Ref + browseModpacks: (args: ServerSettingsBrowseModpacksArgs) => void | Promise +} + +export const [injectServerSettings, provideServerSettings] = createContext( + 'ServerSettings', + 'serverSettingsContext', +) diff --git a/packages/ui/src/layouts/shared/server-settings/tabs.ts b/packages/ui/src/layouts/shared/server-settings/tabs.ts new file mode 100644 index 0000000000..82427d4288 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/tabs.ts @@ -0,0 +1,98 @@ +import type { Archon } from '@modrinth/api-client' +import { + CardIcon, + ListIcon, + ModrinthIcon, + SettingsIcon, + TextQuoteIcon, + VersionIcon, + WrenchIcon, +} from '@modrinth/assets' +import type { Component } from 'vue' + +export type ServerSettingsTabId = + | 'general' + | 'installation' + | 'network' + | 'properties' + | 'advanced' + | 'billing' + | 'admin-billing' + +export interface ServerSettingsTabContext { + serverId: string + ownerId: string + serverStatus?: Archon.Servers.v0.Status | null + isOwner: boolean + isAdmin: boolean +} + +export interface ServerSettingsTabDefinition { + id: ServerSettingsTabId + label: string + icon: Component + href: (ctx: ServerSettingsTabContext) => string + external?: boolean + shown?: (ctx: ServerSettingsTabContext) => boolean +} + +export const serverSettingsTabDefinitions: ServerSettingsTabDefinition[] = [ + { + id: 'general', + label: 'General', + icon: SettingsIcon, + href: ({ serverId }) => `/hosting/manage/${serverId}/options`, + }, + { + id: 'installation', + label: 'Installation', + icon: WrenchIcon, + href: ({ serverId }) => `/hosting/manage/${serverId}/options/loader`, + }, + { + id: 'network', + label: 'Network', + icon: VersionIcon, + href: ({ serverId }) => `/hosting/manage/${serverId}/options/network`, + }, + { + id: 'properties', + label: 'Properties', + icon: ListIcon, + href: ({ serverId }) => `/hosting/manage/${serverId}/options/properties`, + shown: ({ serverStatus }) => serverStatus !== 'installing', + }, + { + id: 'advanced', + label: 'Advanced', + icon: TextQuoteIcon, + href: ({ serverId }) => `/hosting/manage/${serverId}/options/advanced`, + }, + { + id: 'billing', + label: 'Billing', + icon: CardIcon, + href: ({ serverId }) => `/settings/billing#server-${serverId}`, + external: true, + shown: ({ isOwner }) => isOwner, + }, + { + id: 'admin-billing', + label: 'Admin Billing', + icon: ModrinthIcon, + href: ({ ownerId }) => `/admin/billing/${ownerId}`, + external: true, + shown: ({ isAdmin }) => isAdmin, + }, +] + +export function getServerSettingsNavLinks(ctx: ServerSettingsTabContext) { + return serverSettingsTabDefinitions.map((tab) => ({ + id: tab.id, + icon: tab.icon, + label: tab.label, + href: tab.href(ctx), + external: tab.external, + shown: tab.shown ? tab.shown(ctx) : true, + })) +} diff --git a/packages/ui/src/layouts/wrapped/hosting/manage/index.vue b/packages/ui/src/layouts/wrapped/hosting/manage/index.vue index 45221b3d2d..0752d7df29 100644 --- a/packages/ui/src/layouts/wrapped/hosting/manage/index.vue +++ b/packages/ui/src/layouts/wrapped/hosting/manage/index.vue @@ -1,18 +1,40 @@