mobile_responsiveness_adjustments_tables_grids_and_sidebars
This commit is contained in:
parent
dd4ffff3cc
commit
7bd5f9f0e4
@ -2,7 +2,7 @@ import { Outlet, Link } from '@tanstack/react-router';
|
||||
import { useAuthStore } from '../../hooks/use-auth';
|
||||
import { useThemeStore } from '../../hooks/use-theme';
|
||||
import { motion } from 'framer-motion';
|
||||
import { LayoutDashboard, FolderKanban, FileSignature, Users, LogOut, Hexagon, Sun, Moon } from 'lucide-react';
|
||||
import { LayoutDashboard, FolderKanban, FileSignature, Users, LogOut, Sun, Moon } from 'lucide-react';
|
||||
|
||||
export const MainLayout = () => {
|
||||
const { isAuthenticated, logout, user } = useAuthStore();
|
||||
|
||||
@ -152,8 +152,8 @@ export const AssetManagement: React.FC = () => {
|
||||
<thead>
|
||||
<tr className="border-b border-ink-100 bg-ink-50 text-xs font-bold uppercase tracking-wider text-ink-600">
|
||||
<th className="px-5 py-3.5">Asset Title / Category</th>
|
||||
<th className="px-5 py-3.5">Tags</th>
|
||||
<th className="px-5 py-3.5">Downloads</th>
|
||||
<th className="px-5 py-3.5 hidden md:table-cell">Tags</th>
|
||||
<th className="px-5 py-3.5 hidden sm:table-cell">Downloads</th>
|
||||
<th className="px-5 py-3.5">Status</th>
|
||||
<th className="px-5 py-3.5 text-right">Actions</th>
|
||||
</tr>
|
||||
@ -184,7 +184,7 @@ export const AssetManagement: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-5 py-4">
|
||||
<td className="px-5 py-4 hidden md:table-cell">
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{asset.tags.map(t => (
|
||||
<span key={t} className="rounded bg-ink-50 px-2 py-0.5 text-[10px] font-semibold text-ink-600 border border-ink-100">
|
||||
@ -193,7 +193,7 @@ export const AssetManagement: React.FC = () => {
|
||||
))}
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-5 py-4 font-mono font-semibold text-ink-700">
|
||||
<td className="px-5 py-4 font-mono font-semibold text-ink-700 hidden sm:table-cell">
|
||||
{asset.downloadsCount}
|
||||
</td>
|
||||
<td className="px-5 py-4">
|
||||
|
||||
1
Channel-Frontend/src/fontsource.d.ts
vendored
Normal file
1
Channel-Frontend/src/fontsource.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
declare module '@fontsource-variable/inter';
|
||||
@ -2,13 +2,12 @@ import React, { useEffect, useState } from 'react';
|
||||
import { useSearchParams, useNavigate } from 'react-router-dom';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Shield, CheckCircle, AlertCircle, ChevronRight, KeyRound, Eye, EyeOff } from 'lucide-react';
|
||||
import axios from 'axios';
|
||||
import { axiosInstance } from '../services/axios';
|
||||
import { useAuthStore } from '../hooks/use-auth';
|
||||
import { useToast } from '../hooks/use-toast';
|
||||
|
||||
export const InvitePage: React.FC = () => {
|
||||
const { success, error: toastError } = useToast();
|
||||
const { success } = useToast();
|
||||
const [searchParams] = useSearchParams();
|
||||
const token = searchParams.get('token');
|
||||
const navigate = useNavigate();
|
||||
@ -29,9 +28,10 @@ export const InvitePage: React.FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const validateToken = async () => {
|
||||
// verify token on mount
|
||||
const verifyToken = async () => {
|
||||
try {
|
||||
const response = await axiosInstance.get(`/auth/invite/${token}`);
|
||||
const response = await axiosInstance.get(`/auth/verify-invite?token=${token}`);
|
||||
setEmail(response.data.email);
|
||||
setStatus('valid');
|
||||
} catch (err) {
|
||||
@ -39,7 +39,7 @@ export const InvitePage: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
validateToken();
|
||||
verifyToken();
|
||||
}, [token]);
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
@ -51,25 +51,36 @@ export const InvitePage: React.FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (password.length < 6) {
|
||||
setError('Password must be at least 6 characters');
|
||||
if (password.length < 8) {
|
||||
setError('Password must be at least 8 characters long');
|
||||
return;
|
||||
}
|
||||
|
||||
setIsSubmitting(true);
|
||||
try {
|
||||
const response = await axiosInstance.post('/auth/invite/accept', {
|
||||
const response = await axiosInstance.post('/auth/activate-partner', {
|
||||
token,
|
||||
password
|
||||
});
|
||||
|
||||
setAuth(response.data);
|
||||
success("Account created successfully", "Please complete your partner onboarding profile.");
|
||||
navigate('/onboarding');
|
||||
|
||||
// Show success toast
|
||||
success('Account activated successfully!');
|
||||
|
||||
// Set auth store
|
||||
setAuth({ user: response.data.user, accessToken: response.data.token });
|
||||
|
||||
// Redirect based on role / status
|
||||
setTimeout(() => {
|
||||
if (response.data.user.role === 'ADMIN') {
|
||||
navigate('/admin');
|
||||
} else if (response.data.user.onboardingStatus === 'APPROVED') {
|
||||
navigate('/client');
|
||||
} else {
|
||||
navigate('/onboarding');
|
||||
}
|
||||
}, 1000);
|
||||
} catch (err: any) {
|
||||
const errMsg = err.response?.data?.error || 'Failed to accept invite';
|
||||
setError(errMsg);
|
||||
toastError("Failed to accept invite", errMsg);
|
||||
setError(err.response?.data?.detail || 'Activation failed');
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
@ -77,7 +88,7 @@ export const InvitePage: React.FC = () => {
|
||||
if (status === 'loading') {
|
||||
return (
|
||||
<div className="min-h-screen bg-ink-50 flex items-center justify-center">
|
||||
<div className="w-8 h-8 border-4 border-ink-900/30 border-t-ink-900 rounded-full animate-spin" />
|
||||
<div className="w-8 h-8 border-4 border-ink-900/35 border-t-ink-900 rounded-full animate-spin" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -85,7 +96,7 @@ export const InvitePage: React.FC = () => {
|
||||
if (status === 'invalid') {
|
||||
return (
|
||||
<div className="min-h-screen bg-ink-50 flex items-center justify-center p-4">
|
||||
<div className="w-full max-w-md bg-ink-0 rounded-3xl p-8 border border-ink-200 text-center shadow-2xl">
|
||||
<div className="w-full max-w-md bg-ink-0 rounded-[2rem] p-8 border border-ink-200 shadow-2xl text-center">
|
||||
<div className="w-16 h-16 bg-red-500/10 rounded-full flex items-center justify-center mx-auto mb-6">
|
||||
<AlertCircle className="w-8 h-8 text-red-600 dark:text-red-500" />
|
||||
</div>
|
||||
@ -112,7 +123,9 @@ export const InvitePage: React.FC = () => {
|
||||
<Shield className="w-6 h-6 text-ink-0" />
|
||||
</div>
|
||||
<h1 className="text-3xl login-title font-extrabold tracking-tight mb-2">Welcome to Tech4Biz</h1>
|
||||
<p className="text-sm login-desc text-ink-500">Please set up your password to activate your channel partner account.</p>
|
||||
<p className="text-sm login-desc text-ink-500">
|
||||
Set up your partner account for <span className="text-ink-900 font-bold">{email}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<motion.div
|
||||
|
||||
@ -5,7 +5,7 @@ import { loginUser } from "../services/auth-api";
|
||||
import { useAuthStore } from "../hooks/use-auth";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useState } from "react";
|
||||
import { Hexagon, Lock, Mail, ArrowRight, Eye, EyeOff } from "lucide-react";
|
||||
import { Lock, Mail, ArrowRight, Eye, EyeOff } from "lucide-react";
|
||||
import { motion } from "framer-motion";
|
||||
import { useToast } from "../hooks/use-toast";
|
||||
|
||||
|
||||
@ -341,8 +341,8 @@ export const DirectoryPage: React.FC = () => {
|
||||
<tr>
|
||||
<th className="px-5 py-3">Partner</th>
|
||||
<th className="px-5 py-3">Status</th>
|
||||
<th className="px-5 py-3">MFA</th>
|
||||
<th className="px-5 py-3">Joined</th>
|
||||
<th className="px-5 py-3 hidden sm:table-cell">MFA</th>
|
||||
<th className="px-5 py-3 hidden sm:table-cell">Joined</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-ink-200 bg-ink-0">
|
||||
@ -391,7 +391,7 @@ export const DirectoryPage: React.FC = () => {
|
||||
{sc.label}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-5 py-4">
|
||||
<td className="px-5 py-4 hidden sm:table-cell">
|
||||
{partner.mfaEnabled ? (
|
||||
<span className="text-xs font-bold text-ink-900">
|
||||
Enabled
|
||||
@ -402,7 +402,7 @@ export const DirectoryPage: React.FC = () => {
|
||||
</span>
|
||||
)}
|
||||
</td>
|
||||
<td className="px-5 py-4 text-xs text-ink-500 font-medium">
|
||||
<td className="px-5 py-4 text-xs text-ink-500 font-medium hidden sm:table-cell">
|
||||
{new Date(partner.createdAt).toLocaleDateString()}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user