getServerURL() utility function

This commit is contained in:
Oliver Bryan
2025-12-31 17:00:38 +00:00
parent cb21564c11
commit c7d261048b
8 changed files with 30 additions and 30 deletions

View File

@@ -17,12 +17,10 @@ import {
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuTrigger, DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"; } from "@/components/ui/dropdown-menu";
import { getAuthHeaders } from "@/lib/utils"; import { getAuthHeaders, getServerURL } from "@/lib/utils";
import { ResizablePanel, ResizablePanelGroup, ResizableSeparator } from "./components/ui/resizable"; import { ResizablePanel, ResizablePanelGroup, ResizableSeparator } from "./components/ui/resizable";
function Index() { function Index() {
const serverURL = import.meta.env.VITE_SERVER_URL?.trim() || "http://localhost:3000";
const user = JSON.parse(localStorage.getItem("user") || "{}") as UserRecord; const user = JSON.parse(localStorage.getItem("user") || "{}") as UserRecord;
const organisationsRef = useRef(false); const organisationsRef = useRef(false);
@@ -37,7 +35,7 @@ function Index() {
const refetchOrganisations = async (options?: { selectOrganisationId?: number }) => { const refetchOrganisations = async (options?: { selectOrganisationId?: number }) => {
try { try {
const res = await fetch(`${serverURL}/organisation/by-user?userId=${user.id}`, { const res = await fetch(`${getServerURL()}/organisation/by-user?userId=${user.id}`, {
headers: getAuthHeaders(), headers: getAuthHeaders(),
}); });
const data = (await res.json()) as Array<OrganisationResponse>; const data = (await res.json()) as Array<OrganisationResponse>;
@@ -77,7 +75,7 @@ function Index() {
const refetchProjects = async (organisationId: number, options?: { selectProjectId?: number }) => { const refetchProjects = async (organisationId: number, options?: { selectProjectId?: number }) => {
try { try {
const res = await fetch( const res = await fetch(
`${serverURL}/projects/by-organisation?organisationId=${organisationId}`, `${getServerURL()}/projects/by-organisation?organisationId=${organisationId}`,
{ {
headers: getAuthHeaders(), headers: getAuthHeaders(),
}, },
@@ -126,7 +124,7 @@ function Index() {
const refetchIssues = async (projectKey: string) => { const refetchIssues = async (projectKey: string) => {
try { try {
const res = await fetch(`${serverURL}/issues/${projectKey}`, { const res = await fetch(`${getServerURL()}/issues/${projectKey}`, {
headers: getAuthHeaders(), headers: getAuthHeaders(),
}); });
const data = (await res.json()) as IssueResponse[]; const data = (await res.json()) as IssueResponse[];

View File

@@ -2,9 +2,7 @@ import type { OrganisationResponse, UserRecord } from "@issue/shared";
import { useCallback, useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { OrganisationSelect } from "@/components/organisation-select"; import { OrganisationSelect } from "@/components/organisation-select";
import { SettingsPageLayout } from "@/components/settings-page-layout"; import { SettingsPageLayout } from "@/components/settings-page-layout";
import { getAuthHeaders } from "@/lib/utils"; import { getAuthHeaders, getServerURL } from "@/lib/utils";
const SERVER_URL = import.meta.env.VITE_SERVER_URL?.trim() || "http://localhost:3000";
function Organisations() { function Organisations() {
const user = JSON.parse(localStorage.getItem("user") || "{}") as UserRecord; const user = JSON.parse(localStorage.getItem("user") || "{}") as UserRecord;
@@ -15,7 +13,7 @@ function Organisations() {
const refetchOrganisations = useCallback( const refetchOrganisations = useCallback(
async (options?: { selectOrganisationId?: number }) => { async (options?: { selectOrganisationId?: number }) => {
try { try {
const res = await fetch(`${SERVER_URL}/organisation/by-user?userId=${user.id}`, { const res = await fetch(`${getServerURL()}/organisation/by-user?userId=${user.id}`, {
headers: getAuthHeaders(), headers: getAuthHeaders(),
}); });

View File

@@ -2,6 +2,7 @@ import type { UserRecord } from "@issue/shared";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import Loading from "@/components/loading"; import Loading from "@/components/loading";
import LogInForm from "@/components/login-form"; import LogInForm from "@/components/login-form";
import { getServerURL } from "@/lib/utils";
type AuthProviderProps = { type AuthProviderProps = {
children: React.ReactNode; children: React.ReactNode;
@@ -9,8 +10,6 @@ type AuthProviderProps = {
}; };
export function Auth({ children }: AuthProviderProps) { export function Auth({ children }: AuthProviderProps) {
const serverURL = import.meta.env.VITE_SERVER_URL?.trim() || "http://localhost:3000";
const [loggedIn, setLoggedIn] = useState<boolean>(); const [loggedIn, setLoggedIn] = useState<boolean>();
const fetched = useRef(false); const fetched = useRef(false);
@@ -21,7 +20,7 @@ export function Auth({ children }: AuthProviderProps) {
if (!token) { if (!token) {
return setLoggedIn(false); return setLoggedIn(false);
} }
fetch(`${serverURL}/auth/me`, { fetch(`${getServerURL()}/auth/me`, {
headers: { Authorization: `Bearer ${token}` }, headers: { Authorization: `Bearer ${token}` },
}) })
.then(async (res) => { .then(async (res) => {

View File

@@ -10,7 +10,7 @@ import {
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { cn, getAuthHeaders } from "@/lib/utils"; import { cn, getAuthHeaders, getServerURL } from "@/lib/utils";
export function CreateIssue({ export function CreateIssue({
projectId, projectId,
@@ -21,8 +21,6 @@ export function CreateIssue({
trigger?: React.ReactNode; trigger?: React.ReactNode;
completeAction?: (issueId: number) => void | Promise<void>; completeAction?: (issueId: number) => void | Promise<void>;
}) { }) {
const serverURL = import.meta.env.VITE_SERVER_URL?.trim() || "http://localhost:3000";
const userId = JSON.parse(localStorage.getItem("user") || "{}").id as number | undefined; const userId = JSON.parse(localStorage.getItem("user") || "{}").id as number | undefined;
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
@@ -90,7 +88,7 @@ export function CreateIssue({
setSubmitting(true); setSubmitting(true);
try { try {
const url = new URL(`${serverURL}/issue/create`); const url = new URL(`${getServerURL()}/issue/create`);
url.searchParams.set("projectId", `${projectId}`); url.searchParams.set("projectId", `${projectId}`);
url.searchParams.set("title", title.trim()); url.searchParams.set("title", title.trim());
url.searchParams.set("description", description.trim()); url.searchParams.set("description", description.trim());

View File

@@ -10,7 +10,7 @@ import {
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { cn, getAuthHeaders } from "@/lib/utils"; import { cn, getAuthHeaders, getServerURL } from "@/lib/utils";
const slugify = (value: string) => const slugify = (value: string) =>
value value
@@ -27,8 +27,6 @@ export function CreateOrganisation({
trigger?: React.ReactNode; trigger?: React.ReactNode;
completeAction?: (organisationId: number) => void | Promise<void>; completeAction?: (organisationId: number) => void | Promise<void>;
}) { }) {
const serverURL = import.meta.env.VITE_SERVER_URL?.trim() || "http://localhost:3000";
const userId = JSON.parse(localStorage.getItem("user") || "{}").id as number | undefined; const userId = JSON.parse(localStorage.getItem("user") || "{}").id as number | undefined;
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
@@ -90,7 +88,7 @@ export function CreateOrganisation({
setSubmitting(true); setSubmitting(true);
try { try {
const url = new URL(`${serverURL}/organisation/create`); const url = new URL(`${getServerURL()}/organisation/create`);
url.searchParams.set("name", name.trim()); url.searchParams.set("name", name.trim());
url.searchParams.set("slug", slug.trim()); url.searchParams.set("slug", slug.trim());
url.searchParams.set("userId", `${userId}`); url.searchParams.set("userId", `${userId}`);

View File

@@ -10,7 +10,7 @@ import {
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { cn, getAuthHeaders } from "@/lib/utils"; import { cn, getAuthHeaders, getServerURL } from "@/lib/utils";
const keyify = (value: string) => const keyify = (value: string) =>
value value
@@ -27,8 +27,6 @@ export function CreateProject({
trigger?: React.ReactNode; trigger?: React.ReactNode;
completeAction?: (projectId: number) => void | Promise<void>; completeAction?: (projectId: number) => void | Promise<void>;
}) { }) {
const serverURL = import.meta.env.VITE_SERVER_URL?.trim() || "http://localhost:3000";
const userId = JSON.parse(localStorage.getItem("user") || "{}").id as number | undefined; const userId = JSON.parse(localStorage.getItem("user") || "{}").id as number | undefined;
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
@@ -96,7 +94,7 @@ export function CreateProject({
setSubmitting(true); setSubmitting(true);
try { try {
const url = new URL(`${serverURL}/project/create`); const url = new URL(`${getServerURL()}/project/create`);
url.searchParams.set("key", key); url.searchParams.set("key", key);
url.searchParams.set("name", name.trim()); url.searchParams.set("name", name.trim());
url.searchParams.set("creatorId", `${userId}`); url.searchParams.set("creatorId", `${userId}`);

View File

@@ -3,7 +3,7 @@ import { type ChangeEvent, useEffect, useMemo, useState } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { capitalise, cn } from "@/lib/utils"; import { capitalise, cn, getServerURL } from "@/lib/utils";
function Field({ function Field({
label = "label", label = "label",
@@ -46,8 +46,6 @@ function Field({
} }
export default function LogInForm() { export default function LogInForm() {
const serverURL = import.meta.env.VITE_SERVER_URL?.trim() || "http://localhost:3000";
const [mode, setMode] = useState<"login" | "register">("login"); const [mode, setMode] = useState<"login" | "register">("login");
const [name, setName] = useState(""); const [name, setName] = useState("");
@@ -79,7 +77,7 @@ export default function LogInForm() {
return; return;
} }
fetch(`${serverURL}/auth/login`, { fetch(`${getServerURL()}/auth/login`, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
@@ -111,7 +109,7 @@ export default function LogInForm() {
return; return;
} }
fetch(`${serverURL}/auth/register`, { fetch(`${getServerURL()}/auth/register`, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({

View File

@@ -18,3 +18,16 @@ export function getAuthHeaders(): HeadersInit {
export function capitalise(str: string) { export function capitalise(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1); return str.charAt(0).toUpperCase() + str.slice(1);
} }
const ENV_SERVER_URL = import.meta.env.VITE_SERVER_URL?.trim();
export function getServerURL() {
let serverURL =
localStorage.getItem("serverURL") || // user-defined server URL
ENV_SERVER_URL || // environment variable
"https://eussi.ob248.com"; // fallback
if (serverURL.endsWith("/")) {
serverURL = serverURL.slice(0, -1);
}
return serverURL;
}