Compare commits
7 Commits
main
...
cal/server
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
475ee69cfb | ||
|
|
ab48d4b144 | ||
|
|
3480448351 | ||
|
|
daae37806c | ||
|
|
6a4c140420 | ||
|
|
5d98b16270 | ||
|
|
6c452f86b6 |
@ -50,22 +50,27 @@ const container = ref(null);
|
|||||||
const showLabels = ref(false);
|
const showLabels = ref(false);
|
||||||
|
|
||||||
const locations = ref([
|
const locations = ref([
|
||||||
// Active locations
|
{
|
||||||
{ name: "New York", lat: 40.7128, lng: -74.006, active: true, clicked: false },
|
name: "Vint Hill",
|
||||||
{ name: "Los Angeles", lat: 34.0522, lng: -118.2437, active: true, clicked: false },
|
lat: 38.74724876915715,
|
||||||
{ name: "Miami", lat: 25.7617, lng: -80.1918, active: true, clicked: false },
|
lng: -77.67436507922152,
|
||||||
{ name: "Spokane", lat: 47.667309, lng: -117.411922, active: true, clicked: false },
|
active: true,
|
||||||
{ name: "Dallas", lat: 32.78372, lng: -96.7947, active: true, clicked: false },
|
clicked: false,
|
||||||
// Future Locations
|
},
|
||||||
// { name: "London", lat: 51.5074, lng: -0.1278, active: false, clicked: false },
|
{
|
||||||
// { name: "Frankfurt", lat: 50.1109, lng: 8.6821, active: false, clicked: false },
|
name: "Coventry",
|
||||||
// { name: "Amsterdam", lat: 52.3676, lng: 4.9041, active: false, clicked: false },
|
lat: 52.39751276904742,
|
||||||
// { name: "Paris", lat: 48.8566, lng: 2.3522, active: false, clicked: false },
|
lng: -1.5777183894453757,
|
||||||
// { name: "Singapore", lat: 1.3521, lng: 103.8198, active: false, clicked: false },
|
active: true,
|
||||||
// { name: "Tokyo", lat: 35.6762, lng: 139.6503, active: false, clicked: false },
|
clicked: false,
|
||||||
// { name: "Sydney", lat: -33.8688, lng: 151.2093, active: false, clicked: false },
|
},
|
||||||
// { name: "São Paulo", lat: -23.5505, lng: -46.6333, active: false, clicked: false },
|
{
|
||||||
// { name: "Toronto", lat: 43.6532, lng: -79.3832, active: false, clicked: false },
|
name: "Limburg",
|
||||||
|
lat: 50.40863558430334,
|
||||||
|
lng: 8.062427315007714,
|
||||||
|
active: true,
|
||||||
|
clicked: false,
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const isLocationVisible = (location) => {
|
const isLocationVisible = (location) => {
|
||||||
|
|||||||
@ -34,6 +34,7 @@ export const DEFAULT_FEATURE_FLAGS = validateValues({
|
|||||||
showProjectPageDownloadModalServersPromo: false,
|
showProjectPageDownloadModalServersPromo: false,
|
||||||
showProjectPageCreateServersTooltip: true,
|
showProjectPageCreateServersTooltip: true,
|
||||||
showProjectPageQuickServerButton: false,
|
showProjectPageQuickServerButton: false,
|
||||||
|
showModrinthServersGlobe: false,
|
||||||
// advancedRendering: true,
|
// advancedRendering: true,
|
||||||
// externalLinksNewTab: true,
|
// externalLinksNewTab: true,
|
||||||
// notUsingBlockers: false,
|
// notUsingBlockers: false,
|
||||||
|
|||||||
@ -515,6 +515,98 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section
|
||||||
|
v-if="flags.showModrinthServersGlobe"
|
||||||
|
class="relative mt-24 flex flex-col bg-[radial-gradient(65%_50%_at_50%_-10%,var(--color-brand-highlight)_0%,var(--color-accent-contrast)_100%)] px-3 pt-24 md:mt-48 md:pt-48"
|
||||||
|
>
|
||||||
|
<div class="faded-brand-line absolute left-0 top-0 h-[1px] w-full"></div>
|
||||||
|
<div class="mx-auto flex w-full max-w-7xl flex-col gap-8">
|
||||||
|
<div class="grid grid-cols-1 items-center gap-12 lg:grid-cols-2">
|
||||||
|
<div class="flex flex-col gap-8">
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div
|
||||||
|
class="relative w-fit rounded-full bg-highlight-green px-3 py-1 text-sm font-bold text-brand backdrop-blur-lg"
|
||||||
|
>
|
||||||
|
Server Locations
|
||||||
|
</div>
|
||||||
|
<h1 class="relative m-0 max-w-2xl text-4xl leading-[120%] md:text-7xl">
|
||||||
|
Global Coverage
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-8">
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="grid size-8 place-content-center rounded-full bg-highlight-green">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="text-brand"
|
||||||
|
>
|
||||||
|
<path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" />
|
||||||
|
<circle cx="12" cy="10" r="3" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h2 class="relative m-0 text-xl font-medium leading-[155%] md:text-2xl">
|
||||||
|
Strategic Locations
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
class="relative m-0 max-w-xl text-base font-normal leading-[155%] text-secondary md:text-[18px]"
|
||||||
|
>
|
||||||
|
With servers strategically placed in Vint Hill (USA), Coventry (UK), and Limburg
|
||||||
|
(Germany), we provide excellent coverage across North America and Europe. Each
|
||||||
|
location features high-performance hardware and comprehensive DDoS protection.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="grid size-8 place-content-center rounded-full bg-highlight-blue">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="text-blue"
|
||||||
|
>
|
||||||
|
<path d="M12 2a10 10 0 1 0 10 10" />
|
||||||
|
<path d="M18 13a6 6 0 0 0-6-6" />
|
||||||
|
<path d="M13 2.05a10 10 0 0 1 2 2" />
|
||||||
|
<path d="M19.5 8.5a10 10 0 0 1 2 2" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h2 class="relative m-0 text-xl font-medium leading-[155%] md:text-2xl">
|
||||||
|
Low Latency Connectivity
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
class="relative m-0 max-w-xl text-base font-normal leading-[155%] text-secondary md:text-[18px]"
|
||||||
|
>
|
||||||
|
Our three carefully chosen locations ensure optimal ping times and reliable
|
||||||
|
connections for players across multiple continents. Choose the region closest to
|
||||||
|
you for the best gaming experience.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Globe />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section
|
<section
|
||||||
id="plan"
|
id="plan"
|
||||||
pyro-hash="plan"
|
pyro-hash="plan"
|
||||||
@ -651,6 +743,7 @@ import { useServersFetch } from "~/composables/servers/servers-fetch.ts";
|
|||||||
import LoaderIcon from "~/components/ui/servers/icons/LoaderIcon.vue";
|
import LoaderIcon from "~/components/ui/servers/icons/LoaderIcon.vue";
|
||||||
import ServerPlanSelector from "~/components/ui/servers/marketing/ServerPlanSelector.vue";
|
import ServerPlanSelector from "~/components/ui/servers/marketing/ServerPlanSelector.vue";
|
||||||
import OptionGroup from "~/components/ui/OptionGroup.vue";
|
import OptionGroup from "~/components/ui/OptionGroup.vue";
|
||||||
|
import Globe from "~/components/ui/servers/Globe.vue";
|
||||||
|
|
||||||
const { locale } = useVIntl();
|
const { locale } = useVIntl();
|
||||||
|
|
||||||
@ -842,6 +935,7 @@ async function fetchPaymentData() {
|
|||||||
const selectedProjectId = ref();
|
const selectedProjectId = ref();
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const flags = useFeatureFlags();
|
||||||
const isAtCapacity = computed(
|
const isAtCapacity = computed(
|
||||||
() => isSmallAtCapacity.value && isMediumAtCapacity.value && isLargeAtCapacity.value,
|
() => isSmallAtCapacity.value && isMediumAtCapacity.value && isLargeAtCapacity.value,
|
||||||
);
|
);
|
||||||
|
|||||||
11
apps/frontend/src/pages/servers_new/manage/index.vue
Normal file
11
apps/frontend/src/pages/servers_new/manage/index.vue
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="experimental-styles-within relative mx-auto mb-6 flex min-h-screen w-full max-w-[1280px] flex-col px-6"
|
||||||
|
>
|
||||||
|
<ServersManagePage />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ServersManagePage } from "@modrinth/ui";
|
||||||
|
</script>
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
<svg viewBox="0 0 592 384" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M0 3C0 1.34315 1.34315 0 3 0H93C94.6569 0 96 1.34315 96 3V93C96 94.6569 94.6569 96 93 96H3C1.34315 96 0 94.6569 0 93V3Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M120 18C120 16.8954 120.895 16 122 16H590C591.105 16 592 16.8954 592 18V38C592 39.1046 591.105 40 590 40H122C120.895 40 120 39.1046 120 38V18Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M120 62C120 60.8954 120.895 60 122 60H142C143.105 60 144 60.8954 144 62V82C144 83.1046 143.105 84 142 84H122C120.895 84 120 83.1046 120 82V62Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M160 62C160 60.8954 160.895 60 162 60H298C299.105 60 300 60.8954 300 62V82C300 83.1046 299.105 84 298 84H162C160.895 84 160 83.1046 160 82V62Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M324 62C324 60.8954 324.895 60 326 60H346C347.105 60 348 60.8954 348 62V82C348 83.1046 347.105 84 346 84H326C324.895 84 324 83.1046 324 82V62Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M364 62C364 60.8954 364.895 60 366 60H466C467.105 60 468 60.8954 468 62V82C468 83.1046 467.105 84 466 84H366C364.895 84 364 83.1046 364 82V62Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M0 147C0 145.343 1.34315 144 3 144H93C94.6569 144 96 145.343 96 147V237C96 238.657 94.6569 240 93 240H3C1.34315 240 0 238.657 0 237V147Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M120 162C120 160.895 120.895 160 122 160H590C591.105 160 592 160.895 592 162V182C592 183.105 591.105 184 590 184H122C120.895 184 120 183.105 120 182V162Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M120 206C120 204.895 120.895 204 122 204H142C143.105 204 144 204.895 144 206V226C144 227.105 143.105 228 142 228H122C120.895 228 120 227.105 120 226V206Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M160 206C160 204.895 160.895 204 162 204H298C299.105 204 300 204.895 300 206V226C300 227.105 299.105 228 298 228H162C160.895 228 160 227.105 160 226V206Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M324 206C324 204.895 324.895 204 326 204H346C347.105 204 348 204.895 348 206V226C348 227.105 347.105 228 346 228H326C324.895 228 324 227.105 324 226V206Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M364 206C364 204.895 364.895 204 366 204H466C467.105 204 468 204.895 468 206V226C468 227.105 467.105 228 466 228H366C364.895 228 364 227.105 364 226V206Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M0 291C0 289.343 1.34315 288 3 288H93C94.6569 288 96 289.343 96 291V381C96 382.657 94.6569 384 93 384H3C1.34315 384 0 382.657 0 381V291Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M120 306C120 304.895 120.895 304 122 304H590C591.105 304 592 304.895 592 306V326C592 327.105 591.105 328 590 328H122C120.895 328 120 327.105 120 326V306Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M120 350C120 348.895 120.895 348 122 348H142C143.105 348 144 348.895 144 350V370C144 371.105 143.105 372 142 372H122C120.895 372 120 371.105 120 370V350Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M160 350C160 348.895 160.895 348 162 348H298C299.105 348 300 348.895 300 350V370C300 371.105 299.105 372 298 372H162C160.895 372 160 371.105 160 370V350Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M324 350C324 348.895 324.895 348 326 348H346C347.105 348 348 348.895 348 350V370C348 371.105 347.105 372 346 372H326C324.895 372 324 371.105 324 370V350Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
<path
|
||||||
|
d="M364 350C364 348.895 364.895 348 366 348H466C467.105 348 468 348.895 468 350V370C468 371.105 467.105 372 466 372H366C364.895 372 364 371.105 364 370V350Z"
|
||||||
|
fill="#F3F4F6" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -50,6 +50,7 @@ import _CubeIcon from './icons/cube.svg?component'
|
|||||||
import _CurrencyIcon from './icons/currency.svg?component'
|
import _CurrencyIcon from './icons/currency.svg?component'
|
||||||
import _DashboardIcon from './icons/dashboard.svg?component'
|
import _DashboardIcon from './icons/dashboard.svg?component'
|
||||||
import _DatabaseIcon from './icons/database.svg?component'
|
import _DatabaseIcon from './icons/database.svg?component'
|
||||||
|
import _DotIcon from './icons/dot.svg?component'
|
||||||
import _DownloadIcon from './icons/download.svg?component'
|
import _DownloadIcon from './icons/download.svg?component'
|
||||||
import _DropdownIcon from './icons/dropdown.svg?component'
|
import _DropdownIcon from './icons/dropdown.svg?component'
|
||||||
import _EditIcon from './icons/edit.svg?component'
|
import _EditIcon from './icons/edit.svg?component'
|
||||||
@ -243,6 +244,7 @@ export const CubeIcon = _CubeIcon
|
|||||||
export const CurrencyIcon = _CurrencyIcon
|
export const CurrencyIcon = _CurrencyIcon
|
||||||
export const DashboardIcon = _DashboardIcon
|
export const DashboardIcon = _DashboardIcon
|
||||||
export const DatabaseIcon = _DatabaseIcon
|
export const DatabaseIcon = _DatabaseIcon
|
||||||
|
export const DotIcon = _DotIcon
|
||||||
export const DownloadIcon = _DownloadIcon
|
export const DownloadIcon = _DownloadIcon
|
||||||
export const DropdownIcon = _DropdownIcon
|
export const DropdownIcon = _DropdownIcon
|
||||||
export const EditIcon = _EditIcon
|
export const EditIcon = _EditIcon
|
||||||
|
|||||||
1
packages/assets/icons/dot.svg
Normal file
1
packages/assets/icons/dot.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-dot-icon lucide-dot"><circle cx="12.1" cy="12.1" r="1"/></svg>
|
||||||
|
After Width: | Height: | Size: 264 B |
@ -12,6 +12,7 @@ import './omorphia.scss'
|
|||||||
import _ModrinthIcon from './branding/logo.svg?component'
|
import _ModrinthIcon from './branding/logo.svg?component'
|
||||||
import _FourOhFourNotFound from './branding/404.svg?component'
|
import _FourOhFourNotFound from './branding/404.svg?component'
|
||||||
import _ModrinthPlusIcon from './branding/modrinth-plus.svg?component'
|
import _ModrinthPlusIcon from './branding/modrinth-plus.svg?component'
|
||||||
|
import _ServersManageIllustration from './branding/illustrations/servers-background.svg?component'
|
||||||
import _AngryRinthbot from './branding/rinthbot/angry.webp'
|
import _AngryRinthbot from './branding/rinthbot/angry.webp'
|
||||||
import _AnnoyedRinthbot from './branding/rinthbot/annoyed.webp'
|
import _AnnoyedRinthbot from './branding/rinthbot/annoyed.webp'
|
||||||
import _ConfusedRinthbot from './branding/rinthbot/confused.webp'
|
import _ConfusedRinthbot from './branding/rinthbot/confused.webp'
|
||||||
@ -50,6 +51,7 @@ import _YouTubeIcon from './external/youtube.svg?component'
|
|||||||
export const ModrinthIcon = _ModrinthIcon
|
export const ModrinthIcon = _ModrinthIcon
|
||||||
export const FourOhFourNotFound = _FourOhFourNotFound
|
export const FourOhFourNotFound = _FourOhFourNotFound
|
||||||
export const ModrinthPlusIcon = _ModrinthPlusIcon
|
export const ModrinthPlusIcon = _ModrinthPlusIcon
|
||||||
|
export const ServersManageIllustration = _ServersManageIllustration
|
||||||
export const AngryRinthbot = _AngryRinthbot
|
export const AngryRinthbot = _AngryRinthbot
|
||||||
export const AnnoyedRinthbot = _AnnoyedRinthbot
|
export const AnnoyedRinthbot = _AnnoyedRinthbot
|
||||||
export const ConfusedRinthbot = _ConfusedRinthbot
|
export const ConfusedRinthbot = _ConfusedRinthbot
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
export * from './src/components'
|
export * from './src/components'
|
||||||
export * from './src/utils'
|
export * from './src/utils'
|
||||||
export * from './src/composables'
|
export * from './src/composables'
|
||||||
|
export * from './src/servers'
|
||||||
|
|||||||
5
packages/ui/src/components/base/RaisedBadge.vue
Normal file
5
packages/ui/src/components/base/RaisedBadge.vue
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex items-center gap-2 w-fit px-3 py-1 bg-button-bg rounded-full text-sm">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -36,6 +36,7 @@ export { default as ProgressBar } from './base/ProgressBar.vue'
|
|||||||
export { default as ProjectCard } from './base/ProjectCard.vue'
|
export { default as ProjectCard } from './base/ProjectCard.vue'
|
||||||
export { default as RadialHeader } from './base/RadialHeader.vue'
|
export { default as RadialHeader } from './base/RadialHeader.vue'
|
||||||
export { default as RadioButtons } from './base/RadioButtons.vue'
|
export { default as RadioButtons } from './base/RadioButtons.vue'
|
||||||
|
export { default as RaisedBadge } from './base/RaisedBadge.vue'
|
||||||
export { default as ScrollablePanel } from './base/ScrollablePanel.vue'
|
export { default as ScrollablePanel } from './base/ScrollablePanel.vue'
|
||||||
export { default as ServerNotice } from './base/ServerNotice.vue'
|
export { default as ServerNotice } from './base/ServerNotice.vue'
|
||||||
export { default as SimpleBadge } from './base/SimpleBadge.vue'
|
export { default as SimpleBadge } from './base/SimpleBadge.vue'
|
||||||
|
|||||||
0
packages/ui/src/servers/components/.gitkeep
Normal file
0
packages/ui/src/servers/components/.gitkeep
Normal file
141
packages/ui/src/servers/components/management/ServerCard.vue
Normal file
141
packages/ui/src/servers/components/management/ServerCard.vue
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
<template>
|
||||||
|
<Card>
|
||||||
|
<div class="server-card-grid">
|
||||||
|
<div class="header-section flex gap-4 items-center mb-4">
|
||||||
|
<Avatar size="4rem" />
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<span class="text-xl text-contrast font-bold">{{ server_name }}</span>
|
||||||
|
<span class="text-md text-secondary" v-tooltip="server_created.toLocaleString()">
|
||||||
|
Created {{ formatRelativeTime(server_created) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="badges-section flex gap-2 items-center mb-4">
|
||||||
|
<RaisedBadge>{{ server_plan }}</RaisedBadge>
|
||||||
|
<RaisedBadge class="text-lg" :color="serverStatusColor">
|
||||||
|
• {{ formattedServerStatus }}
|
||||||
|
</RaisedBadge>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-section flex flex-col gap-2 mb-4">
|
||||||
|
<div class="flex flex-row gap-2">
|
||||||
|
<UsersIcon class="size-4 my-auto" />
|
||||||
|
<span class="text-secondary">
|
||||||
|
{{ players_online }} / {{ max_players_online }} players
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row gap-2">
|
||||||
|
<GlobeIcon class="size-4 my-auto" />
|
||||||
|
<span class="text-secondary">{{ world_name }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row gap-2">
|
||||||
|
<LinkIcon class="size-4 my-auto" />
|
||||||
|
<CopyCode :text="ip" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="actions-section flex gap-2">
|
||||||
|
<ButtonStyled color="brand">
|
||||||
|
<RouterLink :to="`/servers/manage/${id}`">
|
||||||
|
<EditIcon class="size-4" />
|
||||||
|
Manage
|
||||||
|
</RouterLink>
|
||||||
|
</ButtonStyled>
|
||||||
|
<ButtonStyled>
|
||||||
|
<RouterLink :to="`/servers/manage/${id}`">
|
||||||
|
<CurrencyIcon class="size-4" />
|
||||||
|
Billing
|
||||||
|
</RouterLink>
|
||||||
|
</ButtonStyled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { CurrencyIcon, EditIcon, GlobeIcon, LinkIcon, UsersIcon } from '@modrinth/assets'
|
||||||
|
import { Avatar, Card, RaisedBadge, useRelativeTime, CopyCode, ButtonStyled } from '@modrinth/ui'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { RouterLink } from 'vue-router'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
server_name: string
|
||||||
|
server_created: Date
|
||||||
|
server_plan: string
|
||||||
|
server_status: string
|
||||||
|
players_online: number
|
||||||
|
max_players_online: number
|
||||||
|
world_name: string
|
||||||
|
ip: string
|
||||||
|
id: string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const formatRelativeTime = useRelativeTime()
|
||||||
|
|
||||||
|
const serverStatusColor = computed(() => {
|
||||||
|
switch (props.server_status) {
|
||||||
|
case 'online':
|
||||||
|
return 'green'
|
||||||
|
case 'restarting':
|
||||||
|
return 'orange'
|
||||||
|
case 'offline':
|
||||||
|
return undefined
|
||||||
|
default:
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const formattedServerStatus = computed(() => {
|
||||||
|
return props.server_status.slice(0, 1).toUpperCase() + props.server_status.slice(1)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.server-card-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas:
|
||||||
|
'header badges'
|
||||||
|
'content content'
|
||||||
|
'actions actions';
|
||||||
|
grid-template-columns: 1fr auto;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.server-card-grid {
|
||||||
|
grid-template-areas:
|
||||||
|
'header'
|
||||||
|
'badges'
|
||||||
|
'content'
|
||||||
|
'actions';
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badges-section {
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 769px) {
|
||||||
|
.badges-section {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-section {
|
||||||
|
grid-area: header;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badges-section {
|
||||||
|
grid-area: badges;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-section {
|
||||||
|
grid-area: content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-section {
|
||||||
|
grid-area: actions;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
0
packages/ui/src/servers/composables/.gitkeep
Normal file
0
packages/ui/src/servers/composables/.gitkeep
Normal file
1
packages/ui/src/servers/index.ts
Normal file
1
packages/ui/src/servers/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default as ServersManagePage } from './pages/manage.vue'
|
||||||
0
packages/ui/src/servers/pages/.gitkeep
Normal file
0
packages/ui/src/servers/pages/.gitkeep
Normal file
130
packages/ui/src/servers/pages/manage.vue
Normal file
130
packages/ui/src/servers/pages/manage.vue
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="servers.length + sharedServers.length === 0" class="text-center py-24 relative">
|
||||||
|
<ServersManageIllustration class="servers-manage-illustration" />
|
||||||
|
<ServerIcon class="size-24 mx-auto text-contrast mb-4" />
|
||||||
|
<h3 class="text-3xl font-medium text-contrast mb-2">No servers found</h3>
|
||||||
|
<p class="text-gray-500 mb-6 px-4">Get started by creating your first server</p>
|
||||||
|
<ButtonStyled color="green" size="large" type="outlined">
|
||||||
|
<button class="flex items-center justify-center gap-2 mx-auto">
|
||||||
|
<PlusIcon class="size-4" /> New server
|
||||||
|
</button>
|
||||||
|
</ButtonStyled>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else class="flex flex-col sm:flex-row gap-4 sm:gap-0 my-4">
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<span class="text-3xl text-contrast font-bold">Servers</span>
|
||||||
|
<span class="text-sm sm:text-base text-secondary">View and manage all your servers</span>
|
||||||
|
</div>
|
||||||
|
<div class="sm:ml-auto">
|
||||||
|
<ButtonStyled color="green" size="large" class="w-full sm:w-auto">
|
||||||
|
<button class="flex items-center justify-center gap-2">
|
||||||
|
<PlusIcon class="size-4" />
|
||||||
|
<span>New server</span>
|
||||||
|
</button>
|
||||||
|
</ButtonStyled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template v-if="servers.length > 0">
|
||||||
|
<span class="text-xl text-contrast font-bold mb-4 flex flex-row gap-2"> Your servers </span>
|
||||||
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4 gap-y-2">
|
||||||
|
<ServerCard
|
||||||
|
v-for="server in servers"
|
||||||
|
:id="server.id"
|
||||||
|
:key="server.id"
|
||||||
|
:server_name="server.server_name"
|
||||||
|
:server_created="server.server_created"
|
||||||
|
:server_plan="server.server_plan"
|
||||||
|
:server_status="server.server_status"
|
||||||
|
:players_online="server.players_online"
|
||||||
|
:max_players_online="server.max_players_online"
|
||||||
|
:world_name="server.world_name"
|
||||||
|
:ip="server.ip"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="sharedServers.length > 0">
|
||||||
|
<span class="text-xl text-contrast font-bold mb-4 flex flex-row gap-2"> Shared servers </span>
|
||||||
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4 gap-y-2">
|
||||||
|
<ServerCard
|
||||||
|
v-for="server in sharedServers"
|
||||||
|
:id="server.id"
|
||||||
|
:key="server.id"
|
||||||
|
:server_name="server.server_name"
|
||||||
|
:server_created="server.server_created"
|
||||||
|
:server_plan="server.server_plan"
|
||||||
|
:server_status="server.server_status"
|
||||||
|
:players_online="server.players_online"
|
||||||
|
:max_players_online="server.max_players_online"
|
||||||
|
:world_name="server.world_name"
|
||||||
|
:ip="server.ip"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { ButtonStyled } from '@modrinth/ui'
|
||||||
|
import ServerCard from '../components/management/ServerCard.vue'
|
||||||
|
import { PlusIcon, ServerIcon, ServersManageIllustration } from '@modrinth/assets'
|
||||||
|
|
||||||
|
const sharedServers = ref([
|
||||||
|
{
|
||||||
|
id: 'server-1',
|
||||||
|
server_name: 'Rinth SMP',
|
||||||
|
server_created: new Date('2023-10-01T12:00:00Z'),
|
||||||
|
server_plan: 'Large',
|
||||||
|
server_status: 'online',
|
||||||
|
players_online: 5,
|
||||||
|
max_players_online: 20,
|
||||||
|
world_name: 'Example World',
|
||||||
|
ip: 'valiant-apple.modrinth.gg',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// const sharedServers = ref([])
|
||||||
|
// const servers = ref([])
|
||||||
|
|
||||||
|
const servers = ref([
|
||||||
|
{
|
||||||
|
id: 'server-1',
|
||||||
|
server_name: 'Rinth SMP',
|
||||||
|
server_created: new Date('2023-10-01T12:00:00Z'),
|
||||||
|
server_plan: 'Large',
|
||||||
|
server_status: 'online',
|
||||||
|
players_online: 5,
|
||||||
|
max_players_online: 20,
|
||||||
|
world_name: 'Example World',
|
||||||
|
ip: 'valiant-apple.modrinth.gg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'server-1',
|
||||||
|
server_name: 'Rinth SMP',
|
||||||
|
server_created: new Date('2023-10-01T12:00:00Z'),
|
||||||
|
server_plan: 'Large',
|
||||||
|
server_status: 'online',
|
||||||
|
players_online: 5,
|
||||||
|
max_players_online: 20,
|
||||||
|
world_name: 'Example World',
|
||||||
|
ip: 'valiant-apple.modrinth.gg',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.servers-manage-illustration {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: -1;
|
||||||
|
width: 500px;
|
||||||
|
height: 500px;
|
||||||
|
opacity: 0.05;
|
||||||
|
mask: linear-gradient(to bottom, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0) 100%);
|
||||||
|
-webkit-mask: linear-gradient(to bottom, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0) 100%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
x
Reference in New Issue
Block a user