Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 32 additions & 7 deletions backend/app/database/weaviate/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
logger = logging.getLogger(__name__)

_client = None
_connected = False


def get_client():
Expand All @@ -15,18 +16,42 @@ def get_client():
_client = weaviate.use_async_with_local()
return _client


async def ensure_connected():
"""Ensure the client is connected. Reuses existing connection if available."""
global _client, _connected
client = get_client()

if not _connected or not client.is_connected():
await client.connect()
_connected = True
logger.info("Weaviate client connected")

return client


@asynccontextmanager
async def get_weaviate_client() -> AsyncGenerator[weaviate.WeaviateClient, None]:
"""Async context manager for Weaviate client."""
client = get_client()
"""Async context manager for Weaviate client with persistent connection."""
try:
await client.connect()
client = await ensure_connected()
yield client
except Exception as e:
logger.error(f"Weaviate client error: {str(e)}")
logger.error("Weaviate client error: %s", e)
raise
finally:


async def close_weaviate_client():
"""Close the Weaviate client. Call this on application shutdown."""
global _client, _connected

if _client is not None and _connected:
try:
await client.close()
await _client.close()
_connected = False
logger.info("Weaviate client closed")
except Exception as e:
logger.warning(f"Error closing Weaviate client: {str(e)}")
logger.warning("Error closing Weaviate client: %s", e)
finally:
_client = None
_connected = False
2 changes: 2 additions & 0 deletions backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
import sys
from contextlib import asynccontextmanager
from app.database.weaviate.client import close_weaviate_client

import uvicorn
from fastapi import FastAPI, Response
Expand Down Expand Up @@ -99,6 +100,7 @@ async def lifespan(app: FastAPI):
app.state.app_instance = app_instance
await app_instance.start_background_tasks()
yield
await close_weaviate_client()
await app_instance.stop_background_tasks()


Expand Down
634 changes: 593 additions & 41 deletions landing/package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions landing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
"preview": "vite preview"
},
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@mui/material": "^7.3.7",
"@studio-freight/lenis": "^1.0.42",
"framer-motion": "^10.16.4",
"lucide-react": "^0.344.0",
Expand Down
196 changes: 143 additions & 53 deletions landing/src/components/layout/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,74 +1,164 @@
import React from 'react';
import { Github, Twitter, Linkedin } from 'lucide-react';
import { motion } from 'framer-motion';
import { Github, Twitter, Linkedin, Mail, ArrowUp } from 'lucide-react';
import { useLocation, Link } from 'react-router-dom';

const Footer: React.FC = () => {
const currentYear = new Date().getFullYear();
const location = useLocation();
const isHomePage = location.pathname === '/';

const scrollToTop = () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
};

const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
delayChildren: 0.2,
},
},
};

const itemVariants = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 },
};

const socialLinks = [
{
icon: Github,
href: 'https://github.com/AOSSIE-Org/Devr.AI/',
label: 'GitHub',
color: 'hover:text-green-400'
},
{
icon: Twitter,
href: 'https://x.com/aossie_org?lang=en',
label: 'Twitter',
color: 'hover:text-cyan-400'
},
{
icon: Linkedin,
href: 'https://www.linkedin.com/company/aossie/?originalSubdomain=au',
label: 'LinkedIn',
color: 'hover:text-green-400'
},
];

return (
<footer className="relative bg-gradient-to-br from-dark via-dark-lighter to-gray-900 py-12 overflow-hidden">
{/* Background gradient overlays */}
<footer className="relative bg-gradient-to-br from-dark via-dark-lighter to-gray-900 py-16 overflow-hidden border-t border-gray-800">
{/* Enhanced Background Effects */}
<div className="absolute inset-0 pointer-events-none">
<div className="absolute top-0 left-0 w-96 h-96 rounded-full bg-green-500/5 blur-2xl -translate-x-1/2 -translate-y-1/2"></div>
<div className="absolute bottom-0 right-0 w-96 h-96 rounded-full bg-blue-500/4 blur-3xl translate-x-1/2 translate-y-1/2"></div>
<div className="absolute inset-0 bg-gradient-to-t from-transparent via-green-500/5 to-transparent opacity-50"></div>
<div className="absolute top-0 left-0 w-96 h-96 rounded-full bg-green-500/5 blur-3xl -translate-x-1/2 -translate-y-1/2"></div>
<div className="absolute bottom-0 right-0 w-96 h-96 rounded-full bg-cyan-500/5 blur-3xl translate-x-1/2 translate-y-1/2"></div>
<div className="absolute inset-0 bg-grid-pattern opacity-20"></div>
</div>

<div className="container mx-auto px-6 relative z-10">
<div className="flex flex-col md:flex-row justify-between items-start mb-8">
<div className="mb-6 md:mb-0">
<h3 className="text-2xl font-bold gradient-text mb-2">Devr.AI</h3>
<p className="text-gray-300 text-sm max-w-xs leading-relaxed">
<motion.div
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
className="grid grid-cols-1 md:grid-cols-4 gap-12 mb-12"
>
{/* Brand Section */}
<motion.div variants={itemVariants} className="md:col-span-2">
<h3 className="text-3xl font-bold gradient-text mb-4">Devr.AI</h3>
<p className="text-gray-400 text-base max-w-md leading-relaxed mb-6">
Revolutionizing developer relations with AI-powered community management.
Automate engagement, streamline onboarding, and deliver real-time updates.
</p>
</div>
<div className="flex flex-row gap-12">
<div>
<h4 className="font-semibold mb-4 text-white bg-gradient-to-r from-green-400 to-blue-500 bg-clip-text text-transparent">Links</h4>
<ul className="space-y-3">
<li><a href={isHomePage ? "#features" : "/#features"} className="text-gray-300 hover:text-transparent hover:bg-gradient-to-r hover:from-green-400 hover:to-blue-500 hover:bg-clip-text text-sm transition-all duration-300 ease-in-out">Features</a></li>
<li><a href={isHomePage ? "#how-it-works" : "/#how-it-works"} className="text-gray-300 hover:text-transparent hover:bg-gradient-to-r hover:from-green-400 hover:to-blue-500 hover:bg-clip-text text-sm transition-all duration-300 ease-in-out">How It Works</a></li>
<li><a href={isHomePage ? "#integrations" : "/#integrations"} className="text-gray-300 hover:text-transparent hover:bg-gradient-to-r hover:from-green-400 hover:to-blue-500 hover:bg-clip-text text-sm transition-all duration-300 ease-in-out">Integrations</a></li>
<li><a href={isHomePage ? "#waitlist" : "/#waitlist"} className="text-gray-300 hover:text-transparent hover:bg-gradient-to-r hover:from-green-400 hover:to-blue-500 hover:bg-clip-text text-sm transition-all duration-300 ease-in-out">Join Waitlist</a></li>
</ul>
<div className="flex gap-4">
{socialLinks.map((social) => (
<motion.a
key={social.label}
href={social.href}
target="_blank"
rel="noreferrer"
className={`text-gray-400 ${social.color} transition-colors duration-300 p-3 rounded-xl bg-gray-800/50 hover:bg-gray-800 border border-gray-700 hover:border-gray-600`}
whileHover={{ scale: 1.1, y: -2 }}
whileTap={{ scale: 0.95 }}
aria-label={social.label}
>
<social.icon size={20} />
</motion.a>
))}
</div>
<div>
<h4 className="font-semibold mb-4 text-white bg-gradient-to-r from-green-400 to-blue-500 bg-clip-text text-transparent">Legal</h4>
<ul className="space-y-3">
<li><Link to="/privacy-policy" className="text-gray-300 hover:text-transparent hover:bg-gradient-to-r hover:from-green-400 hover:to-blue-500 hover:bg-clip-text text-sm transition-all duration-300 ease-in-out">Privacy Policy</Link></li>
<li><Link to="/terms-of-service" className="text-gray-300 hover:text-transparent hover:bg-gradient-to-r hover:from-green-400 hover:to-blue-500 hover:bg-clip-text text-sm transition-all duration-300 ease-in-out">Terms of Service</Link></li>
</ul>
</div>
</div>
</div>
</motion.div>

{/* Links Section */}
<motion.div variants={itemVariants}>
<h4 className="font-bold mb-4 text-white text-lg">Quick Links</h4>
<ul className="space-y-3">
{[
{ label: 'Features', href: '#features' },
{ label: 'How It Works', href: '#how-it-works' },
{ label: 'Integrations', href: '#integrations' },
{ label: 'Join Waitlist', href: '#waitlist' },
].map((link) => (
<li key={link.label}>
<a
href={isHomePage ? link.href : `/${link.href}`}
className="text-gray-400 hover:text-green-400 text-sm transition-colors duration-300 inline-flex items-center gap-2 group"
>
<span className="w-0 h-0.5 bg-gradient-to-r from-green-400 to-cyan-400 group-hover:w-4 transition-all duration-300"></span>
{link.label}
</a>
</li>
))}
</ul>
</motion.div>

<div className="border-t border-gradient-to-r from-green-500/20 via-blue-500/20 to-green-500/20 pt-8 flex flex-col md:flex-row justify-between items-center" style={{borderImage: 'linear-gradient(90deg, rgba(34, 197, 94, 0.2), rgba(59, 130, 246, 0.2), rgba(34, 197, 94, 0.2)) 1'}}>
<p className="text-gray-400 text-sm mb-4 md:mb-0">
&copy; {currentYear} Devr.AI. All rights reserved.
{/* Legal Section */}
<motion.div variants={itemVariants}>
<h4 className="font-bold mb-4 text-white text-lg">Legal</h4>
<ul className="space-y-3">
{[
{ label: 'Privacy Policy', to: '/privacy-policy' },
{ label: 'Terms of Service', to: '/terms-of-service' },
].map((link) => (
<li key={link.label}>
<Link
to={link.to}
className="text-gray-400 hover:text-cyan-400 text-sm transition-colors duration-300 inline-flex items-center gap-2 group"
>
<span className="w-0 h-0.5 bg-gradient-to-r from-cyan-400 to-green-400 group-hover:w-4 transition-all duration-300"></span>
{link.label}
</Link>
</li>
))}
</ul>
</motion.div>
</motion.div>

{/* Bottom Bar */}
<motion.div
variants={itemVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
className="pt-8 border-t border-gray-800 flex flex-col md:flex-row justify-between items-center gap-4"
>
<p className="text-gray-500 text-sm">
Β© {currentYear} Devr.AI. All rights reserved.
</p>
<div className="flex space-x-6">
<a href="https://github.com/AOSSIE-Org/Devr.AI/"
className="text-gray-300 hover:text-white hover:scale-110 transition-all duration-300 ease-in-out p-2 rounded-lg hover:bg-gradient-to-r hover:from-green-500/10 hover:to-blue-500/10 hover:shadow-lg hover:shadow-green-500/20"
target='_blank'
rel="noreferrer">
<Github size={20} />
</a>
<a href="https://x.com/aossie_org?lang=en"
className="text-gray-300 hover:text-white hover:scale-110 transition-all duration-300 ease-in-out p-2 rounded-lg hover:bg-gradient-to-r hover:from-green-500/10 hover:to-blue-500/10 hover:shadow-lg hover:shadow-blue-500/20"
target='_blank'
rel="noreferrer">
<Twitter size={20} />
</a>
<a href="https://www.linkedin.com/company/aossie/?originalSubdomain=au"
className="text-gray-300 hover:text-white hover:scale-110 transition-all duration-300 ease-in-out p-2 rounded-lg hover:bg-gradient-to-r hover:from-green-500/10 hover:to-blue-500/10 hover:shadow-lg hover:shadow-green-500/20"
target='_blank'
rel="noreferrer">
<Linkedin size={20} />
</a>
</div>
</div>

{/* Scroll to Top Button */}
<motion.button
onClick={scrollToTop}
className="flex items-center gap-2 text-gray-400 hover:text-green-400 text-sm transition-colors duration-300 group"
whileHover={{ y: -2 }}
whileTap={{ scale: 0.95 }}
>
<span>Back to top</span>
<ArrowUp size={16} className="group-hover:translate-y-[-2px] transition-transform duration-300" />
</motion.button>
</motion.div>
</div>
</footer>
);
Expand Down
2 changes: 1 addition & 1 deletion landing/src/components/layout/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
import { Menu, X, Github } from 'lucide-react';
import { Menu, X} from 'lucide-react';
import { motion } from 'framer-motion';
import { Link, useLocation } from 'react-router-dom';

Expand Down
Loading