This commit is contained in:
Owen
2025-10-04 18:36:44 -07:00
parent 3123f858bb
commit c2c907852d
320 changed files with 35785 additions and 2984 deletions

View File

@@ -0,0 +1,56 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/
"use client";
import RemoteExitNodeContext from "@app/contexts/privateRemoteExitNodeContext";
import { GetRemoteExitNodeResponse } from "@server/routers/private/remoteExitNode";
import { useState } from "react";
import { useTranslations } from "next-intl";
type RemoteExitNodeProviderProps = {
children: React.ReactNode;
remoteExitNode: GetRemoteExitNodeResponse;
};
export function RemoteExitNodeProvider({
children,
remoteExitNode: serverRemoteExitNode
}: RemoteExitNodeProviderProps) {
const [remoteExitNode, setRemoteExitNode] = useState<GetRemoteExitNodeResponse>(serverRemoteExitNode);
const t = useTranslations();
const updateRemoteExitNode = (updatedRemoteExitNode: Partial<GetRemoteExitNodeResponse>) => {
if (!remoteExitNode) {
throw new Error(t('remoteExitNodeErrorNoUpdate'));
}
setRemoteExitNode((prev) => {
if (!prev) {
return prev;
}
return {
...prev,
...updatedRemoteExitNode
};
});
};
return (
<RemoteExitNodeContext.Provider value={{ remoteExitNode, updateRemoteExitNode }}>
{children}
</RemoteExitNodeContext.Provider>
);
}
export default RemoteExitNodeProvider;

View File

@@ -0,0 +1,84 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/
"use client";
import PrivateSubscriptionStatusContext from "@app/contexts/privateSubscriptionStatusContext";
import { getTierPriceSet } from "@server/lib/private/billing/tiers";
import { GetOrgSubscriptionResponse } from "@server/routers/private/billing";
import { useState } from "react";
interface ProviderProps {
children: React.ReactNode;
subscriptionStatus: GetOrgSubscriptionResponse | null;
env: string;
sandbox_mode: boolean;
}
export function PrivateSubscriptionStatusProvider({
children,
subscriptionStatus,
env,
sandbox_mode
}: ProviderProps) {
const [subscriptionStatusState, setSubscriptionStatusState] =
useState<GetOrgSubscriptionResponse | null>(subscriptionStatus);
const updateSubscriptionStatus = (updatedSubscriptionStatus: GetOrgSubscriptionResponse) => {
setSubscriptionStatusState((prev) => {
return {
...updatedSubscriptionStatus
};
});
};
const isActive = () => {
if (subscriptionStatus?.subscription?.status === "active") {
return true;
}
return false;
};
const getTier = () => {
const tierPriceSet = getTierPriceSet(env, sandbox_mode);
if (subscriptionStatus?.items && subscriptionStatus.items.length > 0) {
// Iterate through tiers in order (earlier keys are higher tiers)
for (const [tierId, priceId] of Object.entries(tierPriceSet)) {
// Check if any subscription item matches this tier's price ID
const matchingItem = subscriptionStatus.items.find(item => item.priceId === priceId);
if (matchingItem) {
return tierId;
}
}
}
console.log("No matching tier found");
return null;
};
return (
<PrivateSubscriptionStatusContext.Provider
value={{
subscriptionStatus: subscriptionStatusState,
updateSubscriptionStatus,
isActive,
getTier
}}
>
{children}
</PrivateSubscriptionStatusContext.Provider>
);
}
export default PrivateSubscriptionStatusProvider;

View File

@@ -0,0 +1,59 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/
"use client";
import setGlobalColorTheme from "@app/lib/privateThemeColors";
import { useTheme } from "next-themes";
import { useEffect, useState } from "react";
type ThemeColorStateProps = {
children: React.ReactNode;
colors: any;
};
export default function ThemeDataProvider({
children,
colors
}: ThemeColorStateProps) {
const [isMounted, setIsMounted] = useState(false);
const { theme } = useTheme();
useEffect(() => {
if (!colors) {
setIsMounted(true);
return;
}
let lightOrDark = theme;
if (theme === "system" || !theme) {
lightOrDark = window.matchMedia("(prefers-color-scheme: dark)")
.matches
? "dark"
: "light";
}
setGlobalColorTheme(lightOrDark as "light" | "dark", colors);
if (!isMounted) {
setIsMounted(true);
}
}, [theme]);
if (!isMounted) {
return null;
}
return <>{children}</>;
}