fix: recaptcha badge into inline, CG logo main page with smooth scroll

This commit is contained in:
ssbg04 committed 2026-06-11 16:13:29 +08:00
1 parent ad88525b91
commit e24cf8d0be
11 files changed
+34 -91

No files matched your search

-1
View File
@@ -1 +0,0 @@
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 391 B

-1
View File
@@ -1 +0,0 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

+1 -2
View File
@@ -1,6 +1,6 @@
import { supabase } from "@/lib/supabase";
import ScrollReveal from "@/components/ScrollReveal";
import FloatingBackButton from "@/components/FloatingBackButton";
export const metadata = {
title: "Blog | Cris Charles Garcia",
@@ -14,7 +14,6 @@ export default async function BlogPage() {
return (
<>
<FloatingBackButton />
<ScrollReveal>
<div className="page-hero">
<span className="section-label">Blog</span>
+1 -2
View File
@@ -1,6 +1,6 @@
import { supabase } from "@/lib/supabase";
import ScrollReveal from "@/components/ScrollReveal";
import FloatingBackButton from "@/components/FloatingBackButton";
import { CertCard } from "@/components/ClientCardModals";
export const metadata = {
title: "All Certifications | Cris Charles Garcia",
@@ -14,7 +14,6 @@ export default async function CertificationsPage() {
return (
<>
<FloatingBackButton />
<ScrollReveal>
<div className="page-hero">
<span className="section-label">Certifications</span>
+17 -3
View File
@@ -1,6 +1,7 @@
import { supabase } from "@/lib/supabase";
import ScrollReveal from "@/components/ScrollReveal";
import Link from "next/link";
import Script from "next/script";
import { ProjectCard, ArticleCard, CertCard } from "@/components/ClientCardModals";
export const dynamic = 'force-dynamic';
@@ -252,11 +253,13 @@ export default async function Home() {
<input type="email" name="email" id="form-email" placeholder="Your Email" required />
<input type="text" name="subject" id="form-subject" placeholder="Subject" required />
<textarea name="message" id="form-message" rows={5} placeholder="Message" required></textarea>
<div id="recaptcha-container" style={{ display: 'flex', justifyContent: 'center', margin: '10px 0' }}></div>
{/* reCAPTCHA v3 Enterprise — invisible */}
<script src={`https://www.google.com/recaptcha/enterprise.js?render=${recaptchaSiteKey}`} async defer></script>
<script dangerouslySetInnerHTML={{ __html: `
<Script src={`https://www.google.com/recaptcha/enterprise.js?render=${recaptchaSiteKey}`} strategy="afterInteractive" />
<Script id="recaptcha-inline-script" strategy="afterInteractive">
{`
(function() {
function showToast(type, title, msg) {
var container = document.getElementById('toast-container');
@@ -289,6 +292,16 @@ export default async function Home() {
// Check URL params for status on load
document.addEventListener('DOMContentLoaded', function() {
// Move recaptcha badge inline
var moveBadge = setInterval(function() {
var badge = document.querySelector('.grecaptcha-badge');
var container = document.getElementById('recaptcha-container');
if (badge && container) {
container.appendChild(badge);
clearInterval(moveBadge);
}
}, 500);
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
var msg = params.get('msg');
@@ -358,7 +371,8 @@ export default async function Home() {
});
});
})();
`}} />
`}
</Script>
<button type="submit" className="btn primary full-width" id="btn-send-message">Send Message</button>
</form>
+1 -2
View File
@@ -1,6 +1,6 @@
import { supabase } from "@/lib/supabase";
import ScrollReveal from "@/components/ScrollReveal";
import FloatingBackButton from "@/components/FloatingBackButton";
import { ProjectCard } from "@/components/ClientCardModals";
export const metadata = {
title: "All Projects | Cris Charles Garcia",
@@ -14,7 +14,6 @@ export default async function ProjectsPage() {
return (
<>
<FloatingBackButton />
<ScrollReveal>
<div className="page-hero">
<span className="section-label">Projects</span>
-9
View File
@@ -247,12 +247,3 @@
padding: 16px 18px;
}
}
/* Responsive floating reCAPTCHA badge */
@media (max-width: 768px) {
.grecaptcha-badge {
bottom: 12px !important;
left: 12px !important;
transform: scale(0.8) !important;
transform-origin: bottom left !important;
}
}
+5 -11
View File
@@ -109,16 +109,10 @@
justify-content: center;
}
/* --- Custom reCAPTCHA Badge Styling (Icon Only) --- */
/* --- Custom reCAPTCHA Badge Styling (Inline) --- */
.grecaptcha-badge {
left: 24px !important;
right: auto !important;
bottom: 24px !important;
z-index: 2 !important;
width: 74px !important;
overflow: hidden !important;
transition: none !important;
}
.grecaptcha-badge:hover {
width: 74px !important; /* prevent expansion */
position: static !important;
margin-top: 15px !important;
box-shadow: none !important;
display: block !important;
}
+3 -2
View File
@@ -1,9 +1,10 @@
import { MetadataRoute } from 'next';
export default function sitemap(): MetadataRoute.Sitemap {
const baseUrl = 'https://crischarles.vercel.app';
// const baseUrl = 'https://crischarles.vercel.app';
const baseUrl = 'http://localhost:3000';
const lastMod = '2026-06-11T07:44:07+00:00';
return [
{
url: baseUrl,
-57
View File
@@ -1,57 +0,0 @@
"use client";
import { useRouter } from "next/navigation";
export default function FloatingBackButton() {
const router = useRouter();
return (
<button
onClick={() => router.back()}
className="floating-back-btn"
aria-label="Go back"
title="Go back"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M19 12H5M12 19l-7-7 7-7"/>
</svg>
<style jsx>{`
.floating-back-btn {
position: fixed;
top: 80px; /* Below navbar */
left: 20px;
width: 45px;
height: 45px;
border-radius: 50%;
background: var(--surface);
border: 1px solid var(--border-color);
color: var(--text-light);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 90;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transition: all 0.2s ease;
}
.floating-back-btn:hover {
background: var(--surface-hover);
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
}
.floating-back-btn svg {
width: 20px;
height: 20px;
}
@media (max-width: 768px) {
.floating-back-btn {
top: 70px;
left: 15px;
width: 40px;
height: 40px;
}
}
`}</style>
</button>
);
}
+6 -1
View File
@@ -63,7 +63,12 @@ export default function Navbar() {
<nav id="main-nav">
<div className="logo">
<Link href="/" className="logo-link">CG</Link>
<Link href="/" className="logo-link" onClick={(e) => {
if (window.location.pathname === '/') {
e.preventDefault();
window.scrollTo({ top: 0, behavior: 'smooth' });
}
}}>CG</Link>
<Link href="/admin/login" className="logo-dot-link">.</Link>
</div>