Refactor hostname to become baseurl
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -154,7 +154,7 @@ export function MainLayout() {
|
||||
icon={IconBook}
|
||||
to={`${prefix}/obligations`}
|
||||
/>
|
||||
<SidebarItem
|
||||
<SidebarItem
|
||||
label={__("Continual Improvements")}
|
||||
icon={IconRotateCw}
|
||||
to={`${prefix}/continual-improvements`}
|
||||
@@ -192,15 +192,16 @@ export function MainLayout() {
|
||||
function UserDropdown({ organizationId }: { organizationId: string }) {
|
||||
const { __ } = useTranslate();
|
||||
const { toast } = useToast();
|
||||
const user = useLazyLoadQuery<MainLayoutQueryType>(MainLayoutQuery, { organizationId }).viewer
|
||||
.user;
|
||||
const user = useLazyLoadQuery<MainLayoutQueryType>(MainLayoutQuery, {
|
||||
organizationId,
|
||||
}).viewer.user;
|
||||
|
||||
const handleLogout: React.MouseEventHandler<HTMLAnchorElement> = async (
|
||||
e
|
||||
) => {
|
||||
e.preventDefault();
|
||||
|
||||
fetch(buildEndpoint("/auth/logout"), {
|
||||
fetch(buildEndpoint("/connect/logout"), {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -274,13 +275,19 @@ interface InvitationsResponse {
|
||||
invitations: Invitation[];
|
||||
}
|
||||
|
||||
function OrganizationSelectorWrapper({ organizationId }: { organizationId: string }) {
|
||||
const data = useLazyLoadQuery<MainLayoutQueryType>(MainLayoutQuery, { organizationId });
|
||||
function OrganizationSelectorWrapper({
|
||||
organizationId,
|
||||
}: {
|
||||
organizationId: string;
|
||||
}) {
|
||||
const data = useLazyLoadQuery<MainLayoutQueryType>(MainLayoutQuery, {
|
||||
organizationId,
|
||||
});
|
||||
return <OrganizationSelector currentOrganization={data.organization} />;
|
||||
}
|
||||
|
||||
function OrganizationSelector({
|
||||
currentOrganization
|
||||
currentOrganization,
|
||||
}: {
|
||||
currentOrganization: MainLayoutQueryType["response"]["organization"];
|
||||
}) {
|
||||
@@ -297,32 +304,32 @@ function OrganizationSelector({
|
||||
|
||||
// Fetch organizations and invitations in parallel
|
||||
const [orgsResponse, invitationsResponse] = await Promise.all([
|
||||
fetch('/auth/organizations', { credentials: 'include' }),
|
||||
fetch('/auth/invitations', { credentials: 'include' })
|
||||
fetch("/connect/organizations", { credentials: "include" }),
|
||||
fetch("/connect/invitations", { credentials: "include" }),
|
||||
]);
|
||||
|
||||
if (!orgsResponse.ok) {
|
||||
throw new Error('Failed to fetch organizations');
|
||||
throw new Error("Failed to fetch organizations");
|
||||
}
|
||||
|
||||
if (!invitationsResponse.ok) {
|
||||
throw new Error('Failed to fetch invitations');
|
||||
throw new Error("Failed to fetch invitations");
|
||||
}
|
||||
|
||||
const orgsData: OrganizationsResponse = await orgsResponse.json();
|
||||
const invitationsData: InvitationsResponse = await invitationsResponse.json();
|
||||
const invitationsData: InvitationsResponse =
|
||||
await invitationsResponse.json();
|
||||
|
||||
// Count pending invitations (those without acceptedAt)
|
||||
const pendingCount = invitationsData.invitations.filter(
|
||||
inv => !inv.acceptedAt
|
||||
(inv) => !inv.acceptedAt
|
||||
).length;
|
||||
|
||||
setOrganizations(orgsData.organizations);
|
||||
setPendingInvitationsCount(pendingCount);
|
||||
setError(null);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Unknown error');
|
||||
console.error('Failed to fetch data:', err);
|
||||
setError(err instanceof Error ? err.message : "Unknown error");
|
||||
console.error("Failed to fetch data:", err);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
@@ -334,11 +341,7 @@ function OrganizationSelector({
|
||||
if (error) {
|
||||
return (
|
||||
<div className="flex items-center gap-1">
|
||||
<Button
|
||||
className="-ml-3"
|
||||
variant="tertiary"
|
||||
disabled
|
||||
>
|
||||
<Button className="-ml-3" variant="tertiary" disabled>
|
||||
{__("Error loading organizations")}
|
||||
</Button>
|
||||
</div>
|
||||
@@ -355,7 +358,7 @@ function OrganizationSelector({
|
||||
iconAfter={IconChevronGrabberVertical}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? __("Loading...") : (currentOrganization?.name || "")}
|
||||
{isLoading ? __("Loading...") : currentOrganization?.name || ""}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
@@ -370,7 +373,8 @@ function OrganizationSelector({
|
||||
</div>
|
||||
) : (
|
||||
organizations.map((organization) => {
|
||||
const isAuthenticated = organization.authStatus === "authenticated";
|
||||
const isAuthenticated =
|
||||
organization.authStatus === "authenticated";
|
||||
const isExpired = organization.authStatus === "expired";
|
||||
const needsAuth = organization.authStatus === "unauthenticated";
|
||||
|
||||
@@ -378,16 +382,16 @@ function OrganizationSelector({
|
||||
? `/organizations/${organization.id}`
|
||||
: organization.loginUrl;
|
||||
|
||||
const isSAMLUrl = targetUrl.includes('/auth/saml/');
|
||||
const isSAMLUrl = targetUrl.includes("/connect/saml/");
|
||||
|
||||
return (
|
||||
<DropdownItem
|
||||
asChild
|
||||
key={organization.id}
|
||||
>
|
||||
<DropdownItem asChild key={organization.id}>
|
||||
{isSAMLUrl ? (
|
||||
<a href={targetUrl} className="flex items-center gap-2">
|
||||
<Avatar name={organization.name} src={organization.logoUrl} />
|
||||
<Avatar
|
||||
name={organization.name}
|
||||
src={organization.logoUrl}
|
||||
/>
|
||||
<span className="flex-1">{organization.name}</span>
|
||||
{isAuthenticated && (
|
||||
<IconCheckmark1 size={16} className="text-green-600" />
|
||||
@@ -401,7 +405,10 @@ function OrganizationSelector({
|
||||
</a>
|
||||
) : (
|
||||
<Link to={targetUrl} className="flex items-center gap-2">
|
||||
<Avatar name={organization.name} src={organization.logoUrl} />
|
||||
<Avatar
|
||||
name={organization.name}
|
||||
src={organization.logoUrl}
|
||||
/>
|
||||
<span className="flex-1">{organization.name}</span>
|
||||
{isAuthenticated && (
|
||||
<IconCheckmark1 size={16} className="text-green-600" />
|
||||
|
||||
@@ -51,7 +51,7 @@ export default function OrganizationsPage() {
|
||||
useEffect(() => {
|
||||
const fetchOrganizations = async () => {
|
||||
try {
|
||||
const response = await fetch('/auth/organizations', {
|
||||
const response = await fetch('/connect/organizations', {
|
||||
credentials: 'include',
|
||||
});
|
||||
|
||||
@@ -75,7 +75,7 @@ export default function OrganizationsPage() {
|
||||
useEffect(() => {
|
||||
const fetchInvitations = async () => {
|
||||
try {
|
||||
const response = await fetch('/auth/invitations', {
|
||||
const response = await fetch('/connect/invitations', {
|
||||
credentials: 'include',
|
||||
});
|
||||
|
||||
@@ -98,7 +98,7 @@ export default function OrganizationsPage() {
|
||||
const handleAcceptInvitation = async (invitationId: string, organizationId: string) => {
|
||||
setIsAccepting(true);
|
||||
try {
|
||||
const response = await fetch('/auth/invitations/accept', {
|
||||
const response = await fetch('/connect/invitations/accept', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -281,7 +281,7 @@ function OrganizationCard({ organization }: OrganizationCardProps) {
|
||||
};
|
||||
|
||||
// Check if the URL is a backend SAML endpoint
|
||||
const isSAMLUrl = targetUrl.includes('/auth/saml/');
|
||||
const isSAMLUrl = targetUrl.includes('/connect/saml/');
|
||||
|
||||
return (
|
||||
<Card padded className="w-full">
|
||||
|
||||
@@ -111,7 +111,7 @@ export default function ConfirmEmailPage() {
|
||||
<p className="text-green-600 dark:text-green-400">
|
||||
{__("Your email has been confirmed successfully!")}
|
||||
</p>
|
||||
<Button onClick={() => navigate("/authentication/login")} className="w-full">
|
||||
<Button onClick={() => navigate("/auth/login")} className="w-full">
|
||||
{__("Proceed to Login")}
|
||||
</Button>
|
||||
</div>
|
||||
@@ -141,7 +141,7 @@ export default function ConfirmEmailPage() {
|
||||
{!isConfirmed && (
|
||||
<p className="text-sm text-txt-tertiary">
|
||||
<Link
|
||||
to="/authentication/login"
|
||||
to="/auth/login"
|
||||
className="underline text-txt-primary hover:text-txt-secondary"
|
||||
>
|
||||
{__("Back to Login")}
|
||||
|
||||
@@ -23,7 +23,7 @@ export default function ForgotPasswordPage() {
|
||||
|
||||
const onSubmit = handleSubmit(async (data) => {
|
||||
const response = await fetch(
|
||||
buildEndpoint("/auth/forget-password"),
|
||||
buildEndpoint("/connect/forget-password"),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -81,7 +81,7 @@ export default function ForgotPasswordPage() {
|
||||
<p className="text-sm text-txt-tertiary">
|
||||
{__("Remember your password?")}{" "}
|
||||
<Link
|
||||
to="/authentication/login"
|
||||
to="/auth/login"
|
||||
className="underline text-txt-primary hover:text-txt-secondary"
|
||||
>
|
||||
{__("Back to login")}
|
||||
@@ -124,7 +124,7 @@ export default function ForgotPasswordPage() {
|
||||
<p className="text-sm text-txt-tertiary">
|
||||
{__("Remember your password?")}{" "}
|
||||
<Link
|
||||
to="/authentication/login"
|
||||
to="/auth/login"
|
||||
className="underline text-txt-primary hover:text-txt-secondary"
|
||||
>
|
||||
{__("Back to login")}
|
||||
|
||||
@@ -33,7 +33,7 @@ export default function LoginPage() {
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
const res = await fetch(buildEndpoint("/auth/login"), {
|
||||
const res = await fetch(buildEndpoint("/connect/login"), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -68,7 +68,7 @@ export default function LoginPage() {
|
||||
setIsChecking(true);
|
||||
|
||||
try {
|
||||
const res = await fetch(buildEndpoint("/auth/check-sso"), {
|
||||
const res = await fetch(buildEndpoint("/connect/check-sso"), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -85,7 +85,7 @@ export default function LoginPage() {
|
||||
|
||||
if (data.ssoAvailable && data.samlConfigId) {
|
||||
window.location.href = buildEndpoint(
|
||||
`/auth/saml/login/${data.samlConfigId}`
|
||||
`/connect/saml/login/${data.samlConfigId}`
|
||||
);
|
||||
} else {
|
||||
throw new Error(__("SSO not available for this email domain"));
|
||||
@@ -146,7 +146,7 @@ export default function LoginPage() {
|
||||
|
||||
<div className="text-center mt-6 text-sm text-txt-secondary">
|
||||
{__("Don't have an account ?")}{" "}
|
||||
<Link to="/authentication/register" className="underline hover:text-txt-primary">
|
||||
<Link to="/auth/register" className="underline hover:text-txt-primary">
|
||||
{__("Register")}
|
||||
</Link>
|
||||
</div>
|
||||
@@ -154,7 +154,7 @@ export default function LoginPage() {
|
||||
<div className="text-center text-sm text-txt-secondary">
|
||||
{__("Forgot password?")}{" "}
|
||||
<Link
|
||||
to="/authentication/forgot-password"
|
||||
to="/auth/forgot-password"
|
||||
className="underline hover:text-txt-primary"
|
||||
>
|
||||
{__("Reset password")}
|
||||
@@ -206,7 +206,7 @@ export default function LoginPage() {
|
||||
|
||||
<div className="text-center mt-6 text-sm text-txt-secondary">
|
||||
{__("Don't have an account ?")}{" "}
|
||||
<Link to="/authentication/register" className="underline hover:text-txt-primary">
|
||||
<Link to="/auth/register" className="underline hover:text-txt-primary">
|
||||
{__("Register")}
|
||||
</Link>
|
||||
</div>
|
||||
@@ -214,7 +214,7 @@ export default function LoginPage() {
|
||||
<div className="text-center text-sm text-txt-secondary">
|
||||
{__("Forgot password?")}{" "}
|
||||
<Link
|
||||
to="/authentication/forgot-password"
|
||||
to="/auth/forgot-password"
|
||||
className="underline hover:text-txt-primary"
|
||||
>
|
||||
{__("Reset password")}
|
||||
@@ -257,7 +257,7 @@ export default function LoginPage() {
|
||||
|
||||
<div className="text-center mt-6 text-sm text-txt-secondary">
|
||||
{__("Don't have an account ?")}{" "}
|
||||
<Link to="/authentication/register" className="underline hover:text-txt-primary">
|
||||
<Link to="/auth/register" className="underline hover:text-txt-primary">
|
||||
{__("Register")}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function RegisterPage() {
|
||||
|
||||
const onSubmit = handleSubmit(async (data) => {
|
||||
const response = await fetch(
|
||||
buildEndpoint("/auth/register"),
|
||||
buildEndpoint("/connect/register"),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -106,7 +106,7 @@ export default function RegisterPage() {
|
||||
<p className="text-sm text-txt-tertiary">
|
||||
{__("Already have an account?")}{" "}
|
||||
<Link
|
||||
to="/authentication/login"
|
||||
to="/auth/login"
|
||||
className="underline text-txt-primary hover:text-txt-secondary"
|
||||
>
|
||||
{__("Log in here")}
|
||||
|
||||
@@ -44,7 +44,7 @@ export default function ResetPasswordPage() {
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
buildEndpoint("/auth/reset-password"),
|
||||
buildEndpoint("/connect/reset-password"),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -74,7 +74,7 @@ export default function ResetPasswordPage() {
|
||||
description: __("Password reset successfully"),
|
||||
variant: "success",
|
||||
});
|
||||
navigate("/authentication/login", { replace: true });
|
||||
navigate("/auth/login", { replace: true });
|
||||
});
|
||||
|
||||
usePageTitle(__("Reset password"));
|
||||
@@ -118,7 +118,7 @@ export default function ResetPasswordPage() {
|
||||
<p className="text-sm text-txt-tertiary">
|
||||
{__("Remember your password?")}{" "}
|
||||
<Link
|
||||
to="/authentication/login"
|
||||
to="/auth/login"
|
||||
className="underline text-txt-primary hover:text-txt-secondary"
|
||||
>
|
||||
{__("Log in here")}
|
||||
|
||||
@@ -51,7 +51,7 @@ export default function SignupFromInvitationPage() {
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
buildEndpoint("/auth/signup-from-invitation"),
|
||||
buildEndpoint("/connect/signup-from-invitation"),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -125,7 +125,7 @@ export default function SignupFromInvitationPage() {
|
||||
<p className="text-sm text-txt-tertiary">
|
||||
{__("Already have an account?")}{" "}
|
||||
<Link
|
||||
to="/authentication/login"
|
||||
to="/auth/login"
|
||||
className="underline text-txt-primary hover:text-txt-secondary"
|
||||
>
|
||||
{__("Log in here")}
|
||||
|
||||
@@ -50,7 +50,7 @@ function ErrorBoundary({ error: propsError }: { error?: string }) {
|
||||
const error = useRouteError() ?? propsError;
|
||||
|
||||
if (error instanceof UnAuthenticatedError) {
|
||||
return <Navigate to="/authentication/login" />;
|
||||
return <Navigate to="/auth/login" />;
|
||||
}
|
||||
|
||||
return <PageError error={error?.toString()} />;
|
||||
@@ -58,7 +58,7 @@ function ErrorBoundary({ error: propsError }: { error?: string }) {
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: "/authentication",
|
||||
path: "/auth",
|
||||
Component: AuthLayout,
|
||||
children: [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user