Compare commits

...

3 Commits
master ... main

14 changed files with 120 additions and 47 deletions
Split View
  1. +9
    -6
      .env
  2. +6
    -0
      netlify.toml
  3. +1
    -0
      next.config.js
  4. +9
    -0
      package-lock.json
  5. +3
    -1
      package.json
  6. +1
    -0
      public/_redirects
  7. +0
    -2
      src/components/auth/LoginForm.tsx
  8. +6
    -3
      src/components/dashboard/EventTable.tsx
  9. +16
    -8
      src/components/ui/Button.tsx
  10. +10
    -7
      src/context/AuthContext.tsx
  11. +8
    -6
      src/lib/firebase.ts
  12. +7
    -2
      src/pages/_app.tsx
  13. +37
    -1
      src/pages/dashboard.tsx
  14. +7
    -11
      src/pages/index.tsx

+ 9
- 6
.env View File

@ -1,10 +1,13 @@
# Firebase Configuration
VITE_FIREBASE_API_KEY = AIzaSyCH7XHFOpz9767boAB_OJeeVuqi7wqv6IM
VITE_FIREBASE_AUTH_DOMAIN = niveshweb-b6b85.firebaseapp.com
VITE_FIREBASE_PROJECT_ID = niveshweb-b6b85
VITE_FIREBASE_STORAGE_BUCKET = niveshweb-b6b85.firebasestorage.app
VITE_FIREBASE_MESSAGING_SENDER_ID = 731306267322
VITE_FIREBASE_APP_ID = 1:731306267322:web:a3181d9bcd27d91974a883
NEXT_PUBLIC_FIREBASE_KEY=AIzaSyCH7XHFOpz9767boAB_OJeeVuqi7wqv6IM
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=niveshweb-b6b85.firebaseapp.com
NEXT_PUBLIC_FIREBASE_URL=https://niveshweb-b6b85-default-rtdb.firebaseio.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=niveshweb-b6b85
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=niveshweb-b6b85.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=731306267322
NEXT_PUBLIC_FIREBASE_APPID=1:731306267322:web:a3181d9bcd27d91974a883
NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=G-VW0ZTRXPZ9
# Database Configuration
DB_HOST = 10.0.50.4
DB_USER = pgadmin


+ 6
- 0
netlify.toml View File

@ -0,0 +1,6 @@
[build]
command = "npm run build"
publish = ".next"
[[plugins]]
package = "@netlify/plugin-nextjs"

+ 1
- 0
next.config.js View File

@ -1,6 +1,7 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
// output: 'export',
// If you want to add any API routes, middleware, or special configs, add here
};


+ 9
- 0
package-lock.json View File

@ -8,6 +8,7 @@
"name": "google-events-dashboard",
"version": "0.1.0",
"dependencies": {
"@netlify/plugin-nextjs": "^5.11.2",
"@supabase/supabase-js": "^2.39.0",
"axios": "^1.9.0",
"chart.js": "^4.4.0",
@ -899,6 +900,14 @@
"@tybys/wasm-util": "^0.9.0"
}
},
"node_modules/@netlify/plugin-nextjs": {
"version": "5.11.2",
"resolved": "https://registry.npmjs.org/@netlify/plugin-nextjs/-/plugin-nextjs-5.11.2.tgz",
"integrity": "sha512-9Hgd/J5nP2U/Vv0teytq9uUAGppiKV9t5tzpsuMLqeqUGD9STxXwKmyZd2v8Z4THSW9rw4+8w7dH7LVlFoym2A==",
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@next/env": {
"version": "14.2.29",
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.29.tgz",


+ 3
- 1
package.json View File

@ -6,9 +6,11 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
"lint": "next lint",
"export": "next export"
},
"dependencies": {
"@netlify/plugin-nextjs": "^5.11.2",
"@supabase/supabase-js": "^2.39.0",
"axios": "^1.9.0",
"chart.js": "^4.4.0",


+ 1
- 0
public/_redirects View File

@ -0,0 +1 @@
/* /index.html 200

+ 0
- 2
src/components/auth/LoginForm.tsx View File

@ -1,5 +1,4 @@
import React, { useState } from 'react';
import { LogIn } from 'lucide-react';
import { useAuth } from '../../context/AuthContext';
import Button from '../ui/Button';
import Card, { CardContent, CardHeader, CardTitle } from '../ui/Card';
@ -12,7 +11,6 @@ const LoginForm: React.FC = () => {
const handleGoogleSignIn = async () => {
try {
console.log("DKDKKDOKDODKDKODOD");
setIsLoading(true);
setError(null);
await signInWithGoogle();


+ 6
- 3
src/components/dashboard/EventTable.tsx View File

@ -29,9 +29,12 @@ const EventTable: React.FC<EventTableProps> = ({ events, className = '' }) => {
let aValue = a[sortField as keyof typeof a];
let bValue = b[sortField as keyof typeof b];
if (sortField === 'created_at') {
aValue = new Date(aValue as string).getTime();
bValue = new Date(bValue as string).getTime();
let aVal: string | number = aValue;
let bVal: string | number = bValue;
if (sortField === "created_at") {
aVal = new Date(aValue as string).getTime();
bVal = new Date(bValue as string).getTime();
}
if (aValue === null) return 1;


+ 16
- 8
src/components/ui/Button.tsx View File

@ -22,7 +22,7 @@ const Button: React.FC<ButtonProps> = ({
...props
}) => {
const baseClasses = 'inline-flex items-center justify-center font-medium transition-colors duration-200 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2';
const variantClasses = {
primary: 'bg-primary-500 text-white hover:bg-primary-600 focus:ring-primary-500',
secondary: 'bg-secondary-500 text-white hover:bg-secondary-600 focus:ring-secondary-500',
@ -30,16 +30,16 @@ const Button: React.FC<ButtonProps> = ({
ghost: 'bg-transparent hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-200 focus:ring-primary-500',
danger: 'bg-red-600 text-white hover:bg-red-700 focus:ring-red-500',
};
const sizeClasses = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg',
};
const widthClass = fullWidth ? 'w-full' : '';
const disabledClass = disabled || isLoading ? 'opacity-60 cursor-not-allowed' : '';
return (
<button
className={`${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]} ${widthClass} ${disabledClass} ${className}`}
@ -48,17 +48,25 @@ const Button: React.FC<ButtonProps> = ({
>
{isLoading && (
<svg className="animate-spin -ml-1 mr-2 h-4 w-4 text-current\" xmlns="http://www.w3.org/2000/svg\" fill="none\" viewBox="0 0 24 24">
<circle className="opacity-25\" cx="12\" cy="12\" r="10\" stroke="currentColor\" strokeWidth="4"></circle>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
)}
{!isLoading && icon && iconPosition === 'left' && (
<span className="mr-2">{icon}</span>
)}
{children}
{!isLoading && icon && iconPosition === 'right' && (
<span className="ml-2">{icon}</span>
)}


+ 10
- 7
src/context/AuthContext.tsx View File

@ -6,6 +6,7 @@ import {
onAuthStateChanged
} from 'firebase/auth';
import { auth, googleProvider } from '../lib/firebase';
import { useRouter } from 'next/router';
// import { supabase } from '../lib/supabase';
interface AuthContextType {
@ -30,7 +31,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
const [currentUser, setCurrentUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const [userProfile, setUserProfile] = useState<any | null>(null);
const router = useRouter();
// Function to sync Firebase user with Supabase
const syncUserWithDatabase = async (user: User) => {
if (!user) return null;
@ -72,8 +73,12 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
const signInWithGoogle = async () => {
try {
const result = await signInWithPopup(auth, googleProvider);
const profile = await syncUserWithDatabase(result.user);
setUserProfile(profile);
const profile = result.user;
if (profile?.email?.includes("nivesh.com")) {
setUserProfile(profile);
router.push('/dashboard');
}
} catch (error) {
console.error('Error signing in with Google:', error);
}
@ -93,10 +98,8 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, async (user) => {
setCurrentUser(user);
if (user) {
const profile = await syncUserWithDatabase(user);
setUserProfile(profile);
if (user?.email?.includes("nivesh")) {
setUserProfile(user);
} else {
setUserProfile(null);
}


+ 8
- 6
src/lib/firebase.ts View File

@ -3,12 +3,14 @@ import { getAuth, GoogleAuthProvider } from 'firebase/auth';
// This would typically come from environment variables
const firebaseConfig = {
apiKey:process.env.VITE_FIREBASE_API_KEY || "YOUR_API_KEY",
authDomain:process.env.VITE_FIREBASE_AUTH_DOMAIN || "YOUR_AUTH_DOMAIN",
projectId:process.env.VITE_FIREBASE_PROJECT_ID || "YOUR_PROJECT_ID",
storageBucket:process.env.VITE_FIREBASE_STORAGE_BUCKET || "YOUR_STORAGE_BUCKET",
messagingSenderId:process.env.VITE_FIREBASE_MESSAGING_SENDER_ID || "YOUR_MESSAGING_SENDER_ID",
appId:process.env.VITE_FIREBASE_APP_ID || "YOUR_APP_ID"
apiKey: process.env.NEXT_PUBLIC_FIREBASE_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.NEXT_PUBLIC_FIREBASE_URL,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APPID,
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID
};
// Initialize Firebase


+ 7
- 2
src/pages/_app.tsx View File

@ -1,7 +1,12 @@
// src/pages/_app.tsx
import '../index.css'; // correct path to your Tailwind CSS file
import { AuthProvider } from '../context/AuthContext';
import '../index.css'; // Tailwind ya global styles
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
return (
<AuthProvider>
<Component {...pageProps} />
</AuthProvider>
);
}

+ 37
- 1
src/pages/dashboard.tsx View File

@ -165,6 +165,7 @@ const Dashboard: React.FC = () => {
</div>
);
}
console.log(events, "DKDDKOOKDKDOKDK");
return (
<div className="space-y-6 animate-fade-in">
@ -226,7 +227,42 @@ const Dashboard: React.FC = () => {
</div>
{/* Recent Events Table */}
<EventTable events={events} />
{/* <EventTable events={events} /> */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{events?.map((items, idx) => (
<EventCountCard
title={items?.eventname}
count={items.count}
icon={<Activity size={24} className="text-white" />}
color="bg-primary-500"
change={12}
/>
))}
{/*
<EventCountCard
title="Signups"
count={eventCounts['signup'] || 0}
icon={<Users size={24} className="text-white" />}
color="bg-success-500"
change={5}
/>
<EventCountCard
title="Purchases"
count={eventCounts['purchase'] || 0}
icon={<ShoppingCart size={24} className="text-white" />}
color="bg-accent-500"
change={-3}
/>
<EventCountCard
title="Logins"
count={eventCounts['login'] || 0}
icon={<LogIn size={24} className="text-white" />}
color="bg-secondary-500"
change={8}
/> */}
</div>
</div>
);
};


+ 7
- 11
src/pages/index.tsx View File

@ -1,13 +1,9 @@
// pages/index.tsx
import React from 'react';
// pages/index.js (or pages/index.jsx)
const HomePage = () => {
return (
<div style={{ padding: '2rem' }}>
<h1>Welcome to EventDash!</h1>
<p>This is your homepage (index.tsx)</p>
</div>
);
};
import LoginPage from "./loginPage";
export default HomePage;
// import LoginPage from "@/components/LoginPage"; // Adjust path if needed
export default function Home() {
return <LoginPage />;
}

Loading…
Cancel
Save

Powered by TurnKey Linux.