V 0.1.3
This commit is contained in:
6366
pnpm-lock.yaml
generated
Normal file
6366
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -47,9 +47,11 @@ export function ApiKeyItem({ apiKey, onDelete }: ApiKeyItemProps) {
|
||||
}
|
||||
};
|
||||
|
||||
const displayKey = isVisible
|
||||
const displayKey = isVisible
|
||||
? apiKey.key
|
||||
: apiKey.key.substring(0, 4) + "•".repeat(apiKey.key.length - 8) + apiKey.key.substring(apiKey.key.length - 4);
|
||||
: (apiKey.key && apiKey.key.length >= 8)
|
||||
? apiKey.key.substring(0, 4) + "•".repeat(apiKey.key.length - 8) + apiKey.key.substring(apiKey.key.length - 4)
|
||||
: apiKey.key || "";
|
||||
|
||||
return (
|
||||
<Card className="w-full shadow-sm">
|
||||
|
@@ -40,9 +40,9 @@ export function Header() {
|
||||
|
||||
return (
|
||||
<header>
|
||||
{/* Alpha Disclaimer */}
|
||||
{/* Beta Disclaimer */}
|
||||
<div className="bg-red-500 text-white text-center py-1 text-sm">
|
||||
Alpha Version – Report any issues to{" "}
|
||||
Beta Version – Report any issues to{" "}
|
||||
<a href="mailto:me@mahdium.ir" className="underline">
|
||||
me@mahdium.ir
|
||||
</a>
|
||||
|
@@ -22,7 +22,7 @@ export function Layout() {
|
||||
mahdium.ir
|
||||
</a>
|
||||
</p>
|
||||
<p>Version 0.0.3 - Alpha</p>
|
||||
<p>Version 0.1.3 - Beta</p>
|
||||
</div>
|
||||
</footer>
|
||||
<Toaster position="top-right" />
|
||||
|
@@ -3,12 +3,12 @@ import { toast } from 'sonner';
|
||||
import { getToken, clearToken } from './auth';
|
||||
|
||||
// Set up API base URLs
|
||||
const AUTH_API_URL = 'https://io-a.monasefloadbalancer.ir/auth';
|
||||
const DATA_API_URL = 'https://io-e-cf.monasefloadbalancer.ir/api/user';
|
||||
const USER_DATA_API_URL = 'https://io-userdata.monasefloadbalancer.ir';
|
||||
const DATA_API_URL = 'https://io-data.monasefloadbalancer.ir/api';
|
||||
|
||||
// Create axios instances
|
||||
const authApi = axios.create({
|
||||
baseURL: AUTH_API_URL,
|
||||
const userDataApi = axios.create({
|
||||
baseURL: USER_DATA_API_URL,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
@@ -33,6 +33,17 @@ dataApi.interceptors.request.use(
|
||||
(error) => Promise.reject(error)
|
||||
);
|
||||
|
||||
userDataApi.interceptors.request.use(
|
||||
(config) => {
|
||||
const token = getToken();
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => Promise.reject(error)
|
||||
);
|
||||
|
||||
// Add response interceptor to handle unauthorized errors
|
||||
const handleUnauthorized = (error: any) => {
|
||||
if (error.response && error.response.status === 401) {
|
||||
@@ -45,12 +56,12 @@ const handleUnauthorized = (error: any) => {
|
||||
};
|
||||
|
||||
dataApi.interceptors.response.use((response) => response, handleUnauthorized);
|
||||
authApi.interceptors.response.use((response) => response, handleUnauthorized);
|
||||
userDataApi.interceptors.response.use((response) => response, handleUnauthorized);
|
||||
|
||||
// Auth API functions
|
||||
export const registerUser = async (username: string, password: string, email: string) => {
|
||||
try {
|
||||
const response = await authApi.post('/register', { username, password, email });
|
||||
const response = await userDataApi.post('/auth/register', { username, password, email });
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
throw error.response?.data || { success: false, message: 'Network error' };
|
||||
@@ -59,7 +70,7 @@ export const registerUser = async (username: string, password: string, email: st
|
||||
|
||||
export const loginUser = async (username: string, password: string) => {
|
||||
try {
|
||||
const response = await authApi.post('/login', { username, password });
|
||||
const response = await userDataApi.post('/auth/login', { username, password });
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
throw error.response?.data || { success: false, message: 'Network error' };
|
||||
@@ -69,16 +80,44 @@ export const loginUser = async (username: string, password: string) => {
|
||||
// Data API functions
|
||||
export const getAllFeeds = async () => {
|
||||
try {
|
||||
const response = await dataApi.get('/GetAllFeeds');
|
||||
const response = await userDataApi.get('/api/getallfeeds');
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
throw error.response?.data || { success: false, message: 'Network error' };
|
||||
}
|
||||
};
|
||||
|
||||
export const addNewFeed = async () => {
|
||||
export const updateFeed = async (feedId: string, name: string, isPublic: boolean) => {
|
||||
const token = getToken();
|
||||
if (!token) throw new Error('Authentication required');
|
||||
|
||||
const response = await userDataApi.patch('/api/updatefeed', {
|
||||
feedId,
|
||||
Name: name,
|
||||
IsPublic: isPublic,
|
||||
}, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const addNewFeed = async (name: string, isPublic: boolean) => {
|
||||
const token = getToken();
|
||||
if (!token) throw new Error('Authentication required');
|
||||
|
||||
try {
|
||||
const response = await dataApi.get('/AddNewFeed');
|
||||
const response = await userDataApi.post('/api/addnewfeed', {
|
||||
Name: name,
|
||||
IsPublic: isPublic
|
||||
}, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
throw error.response?.data || { success: false, message: 'Network error' };
|
||||
@@ -87,7 +126,7 @@ export const addNewFeed = async () => {
|
||||
|
||||
export const deleteFeed = async (feedId: string) => {
|
||||
try {
|
||||
const response = await dataApi.delete('/DeleteFeed', {
|
||||
const response = await userDataApi.delete('/api/deletefeed', {
|
||||
data: { feedId }
|
||||
});
|
||||
return response.data;
|
||||
@@ -102,7 +141,7 @@ export const getFeedDataTimeRange = async (
|
||||
endTime: string
|
||||
) => {
|
||||
try {
|
||||
const response = await dataApi.get(`/GetFeedDataTimeRange/${feedId}/${startTime}/${endTime}`);
|
||||
const response = await dataApi.get(`/dash/getfeeddatatimerange/${feedId}/${startTime}/${endTime}`);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
throw error.response?.data || { success: false, message: 'Network error' };
|
||||
@@ -117,7 +156,7 @@ export const createApiKey = async () => {
|
||||
throw new Error('Authentication required');
|
||||
}
|
||||
|
||||
const response = await authApi.get('/createapikey', {
|
||||
const response = await userDataApi.get('/api/createapikey', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
@@ -135,7 +174,7 @@ export const getUserApiKeys = async () => {
|
||||
throw new Error('Authentication required');
|
||||
}
|
||||
|
||||
const response = await authApi.get('/getuserapikeys', {
|
||||
const response = await userDataApi.get('/api/getuserapikeys', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
@@ -153,7 +192,7 @@ export const deleteApiKey = async (ApiKey: string) => {
|
||||
throw new Error('Authentication required');
|
||||
}
|
||||
|
||||
const response = await authApi.delete('/deleteapikey', {
|
||||
const response = await userDataApi.delete('/api/deleteapikey', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
@@ -168,7 +207,7 @@ export const deleteApiKey = async (ApiKey: string) => {
|
||||
export const verifyEmail = async (token: string) => {
|
||||
try {
|
||||
// Call the verify email endpoint with no extra headers or data
|
||||
const response = await authApi.get(`/verifyemail/${token}`);
|
||||
const response = await userDataApi.get(`/auth/verifyemail/${token}`);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
throw error.response?.data || { success: false, message: 'Network error' };
|
||||
|
@@ -25,7 +25,7 @@ export interface ApiKeyResponse {
|
||||
apiKey: string;
|
||||
}
|
||||
|
||||
// New ApiKey Type
|
||||
// New ApiKey Typez
|
||||
export interface ApiKey {
|
||||
createdAt: string;
|
||||
key: string;
|
||||
|
@@ -36,7 +36,11 @@ export function ApiKeysPage() {
|
||||
|
||||
try {
|
||||
const keys = await getUserApiKeys();
|
||||
setApiKeys(keys);
|
||||
const normalizedKeys: ApiKey[] = keys.map((item: { createdAt: any; apiKey: any; }) => ({
|
||||
createdAt: item.createdAt,
|
||||
key: item.apiKey,
|
||||
}));
|
||||
setApiKeys(normalizedKeys);
|
||||
} catch (err: any) {
|
||||
setError(err.message || "Failed to fetch API keys");
|
||||
} finally {
|
||||
|
@@ -56,23 +56,22 @@ export function HomePage() {
|
||||
<div className="grid gap-8 md:grid-cols-3">
|
||||
<div className="flex flex-col items-center text-center p-6 rounded-lg border bg-card shadow-sm">
|
||||
<LineChart className="h-12 w-12 text-primary mb-4" />
|
||||
<h3 className="text-xl font-semibold mb-2">Real-time Visualization</h3>
|
||||
<h3 className="text-xl font-semibold mb-2">Time-based Visualization</h3>
|
||||
<p className="text-muted-foreground">
|
||||
Monitor your IoT device data in real-time with interactive charts and customizable
|
||||
Monitor your IoT device data in thoughout time with interactive charts and customizable
|
||||
dashboards
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center text-center p-6 rounded-lg border bg-card shadow-sm">
|
||||
<ShieldCheck className="h-12 w-12 text-primary mb-4" />
|
||||
<h3 className="text-xl font-semibold mb-2">Secure Communication</h3>
|
||||
<Zap className="h-12 w-12 text-primary mb-4" />
|
||||
<h3 className="text-xl font-semibold mb-2">Lightning-Fast Data Access</h3>
|
||||
<p className="text-muted-foreground">
|
||||
Industry-standard encryption and authentication for all your IoT communications
|
||||
</p>
|
||||
Instantly retrieve and analyze your IoT data with high-speed querying, powered by specialized time-series databases optimized for rapid communication and real-time performance. </p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center text-center p-6 rounded-lg border bg-card shadow-sm">
|
||||
<Zap className="h-12 w-12 text-primary mb-4" />
|
||||
<ShieldCheck className="h-12 w-12 text-primary mb-4" />
|
||||
<h3 className="text-xl font-semibold mb-2">Simple Integration</h3>
|
||||
<p className="text-muted-foreground">
|
||||
Easy-to-use API with comprehensive documentation for quick integration with any device
|
||||
|
Reference in New Issue
Block a user