Skip to content
Open
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
42 changes: 25 additions & 17 deletions components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const Footer: React.FC = () => {
{ name: 'Integrations', href: '#integrations' },
],
resources: [
{ name: 'Documentation', href: 'https://opsimate.vercel.app/#integrations' }, // Placeholder - will link to actual docs
{ name: 'Documentation', href: 'https://opsimate.vercel.app/#integrations' },
],
Comment on lines +15 to 16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

“Documentation” points to an “#integrations” anchor — likely wrong target.

Suggest aligning label and URL:

  • Option A (keep label, fix URL):
-      { name: 'Documentation', href: 'https://opsimate.vercel.app/#integrations' },
+      { name: 'Documentation', href: 'https://opsimate.vercel.app/docs' },
  • Option B (keep URL, fix label):
-      { name: 'Documentation', href: 'https://opsimate.vercel.app/#integrations' },
+      { name: 'Integrations', href: 'https://opsimate.vercel.app/#integrations' },

🌐 Web query:

What is the correct public URL for OpsiMate documentation (docs landing page)? Does an “#integrations” anchor exist on that page?

💡 Result:

The documentation (docs) landing page is: https://opsimate.vercel.app/ . [1][2]

There is no "#integrations" fragment/anchor on that landing page (the Integrations content is a separate docs page at https://opsimate.vercel.app/docs/integrations/overview). [2][3]

Sources:
[1] OpsiMate main site (links to docs).
[2] OpsiMate docs landing (https://opsimate.vercel.app/).
[3] OpsiMate Integrations page (https://opsimate.vercel.app/docs/integrations/overview).


Fix broken documentation link — "#integrations" anchor does not exist.

The "#integrations" anchor does not exist on the docs landing page; integrations content is at https://opsimate.vercel.app/docs/integrations/overview. Correct the link to match the intent:

  • If linking to Documentation: Use https://opsimate.vercel.app/

    -      { name: 'Documentation', href: 'https://opsimate.vercel.app/#integrations' },
    +      { name: 'Documentation', href: 'https://opsimate.vercel.app/' },
  • If linking to Integrations: Use https://opsimate.vercel.app/docs/integrations/overview

    -      { name: 'Documentation', href: 'https://opsimate.vercel.app/#integrations' },
    +      { name: 'Integrations', href: 'https://opsimate.vercel.app/docs/integrations/overview' },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{ name: 'Documentation', href: 'https://opsimate.vercel.app/#integrations' },
],
{ name: 'Documentation', href: 'https://opsimate.vercel.app/' },
],
Suggested change
{ name: 'Documentation', href: 'https://opsimate.vercel.app/#integrations' },
],
{ name: 'Integrations', href: 'https://opsimate.vercel.app/docs/integrations/overview' },
],
🤖 Prompt for AI Agents
In components/Footer.tsx around lines 15 to 16, the Documentation link currently
points to a non-existent "#integrations" anchor; update the href to the correct
target — since the link label is "Documentation" change the href to
"https://opsimate.vercel.app/" (or if the intent was to link specifically to
Integrations instead, set it to
"https://opsimate.vercel.app/docs/integrations/overview"); ensure the new URL
replaces the broken "#integrations" anchor.

opensource: [
{ name: 'GitHub Repository', href: 'https://github.com/OpsiMate/OpsiMate' },
Expand All @@ -25,29 +25,29 @@ const Footer: React.FC = () => {
const socialLinks = [
{
name: 'GitHub',
href: 'https://github.com/OpsiMate/OpsiMate', // From documentation
href: 'https://github.com/OpsiMate/OpsiMate',
icon: Github
},
{
name: 'Slack Community',
href: 'https://join.slack.com/t/opsimate/shared_invite/zt-39bq3x6et-NrVCZzH7xuBGIXmOjJM7gA', // From documentation
href: 'https://join.slack.com/t/opsimate/shared_invite/zt-39bq3x6et-NrVCZzH7xuBGIXmOjJM7gA',
icon: Slack
},
Comment on lines +33 to 35
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Slack invite links expire; use a non‑expiring invite or a vanity redirect (e.g., /community → Slack).

Consider a permanent Slack share link or your own redirect you can rotate without code changes.


🌐 Web query:

How to create a non-expiring Slack workspace invite link and recommended best practices for sharing community invites publicly?

💡 Result:

Short answer — yes. On paid and free Slack workspaces you can create a shared invite link and set it to "Never expires" from Invite people → Copy invite link → Edit link settings → Never expires. By default links are active 30 days and can be reused up to the link-use limit (Slack docs: invite links default 30 days / up to 400 uses; you may see limits or admin/SO settings that remove the option). [1][2]

How to create a non‑expiring invite link (quick steps)

  1. In Slack desktop click your workspace name → Invite people to… → Copy invite link.
  2. Click Edit link settings (in that dialog) and choose “Never expires.” Save and copy the link.
  3. If you don’t see the option, SSO or workspace policies may block invite links — ask an Owner/Admin. [1][2]

Key Slack limits & notes (from Slack)

  • Default invite links: active 30 days and usable up to 400 people. You can change expiration when creating the link.
  • Some workspace/org policies or SSO can remove invite-link creation. If you hit invite limits Slack may restrict invites. [1]

Recommended best practices for publicly sharing community invites

  • Use an intermediate landing page or signup form (adds friction, lets you collect email, show community rules, and block bots with CAPTCHA).
  • Require acceptance of a Code of Conduct / Terms before handing out the link.
  • Enable invitation approvals or set invitation notifications for admins so joins can be reviewed.
  • Limit default channel membership for new users; put sensitive channels private.
  • Monitor and rotate links: periodically deactivate old links and create new ones; keep an audit of shared links.
  • Use rate/abuse controls: limit who can create links, disable self‑invite if spam is a problem, and use moderation tools/bots.
  • Publicize guidelines for behavior and enforcement (and enforce them consistently). [1][2]

Sources

  1. Slack Help — Invite new members / Share an invitation link (steps, defaults, limits). [Slack Help Center]. [turn3search0]
  2. Community guides on setting “Never expires” and practical steps for community Slack invites. [turn1search5]

Replace the expiring Slack invite link with a non-expiring one or a vanity redirect.

The current shared invite link (zt-39bq3x6et-NrVCZzH7xuBGIXmOjJM7gA) will expire in 30 days or after 400 uses by default. Set the link to "Never expires" via Invite people → Copy invite link → Edit link settings, or implement a vanity redirect (e.g., /community → Slack) that you can rotate without code changes. The latter is preferable for maintainability.

🤖 Prompt for AI Agents
In components/Footer.tsx around lines 33 to 35, the Slack invite href currently
points to a temporary shared invite that will expire; replace it with either a
non-expiring Slack invite (set “Never expires” in Slack Invite settings and copy
that link) or, preferably, change the href to a vanity redirect path (e.g.,
"/community") and implement a server- or static redirect from that path to the
current Slack invite so you can rotate links without changing code; update the
href value accordingly and ensure the redirect or new invite is tested.

{
name: 'Email',
href: 'mailto:idan.lut@gmail.com', // Placeholder
href: 'mailto:idan.lut@gmail.com',
icon: Mail
},
];

return (
<footer className="bg-gray-900 text-white">
<footer className="bg-[#FEFEFE] dark:bg-gray-900 text-gray-900 dark:text-white border-t border-gray-200 dark:border-gray-800 transition-colors duration-200">
<div className="container-max section-padding">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-8">
{/* Company Info */}
<div className="lg:col-span-2">
<Logo className="mb-4" />
<p className="text-gray-300 mb-6 max-w-md">
<p className="text-gray-700 dark:text-gray-300 mb-6 max-w-md">
Simplify your infrastructure management with one unified platform.
Monitor, manage, and optimize your entire infrastructure from a single dashboard.
</p>
Expand All @@ -58,7 +58,7 @@ const Footer: React.FC = () => {
<Link
key={social.name}
href={social.href}
className="text-gray-400 hover:text-white transition-colors duration-200"
className="text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-white transition-colors duration-200"
target="_blank"
rel="noopener noreferrer"
aria-label={social.name}
Expand All @@ -72,13 +72,13 @@ const Footer: React.FC = () => {

{/* Product Links */}
<div>
<h3 className="font-semibold text-white mb-4">Product</h3>
<h3 className="font-semibold text-gray-900 dark:text-white mb-4">Product</h3>
<ul className="space-y-2">
{footerLinks.product.map((link) => (
<li key={link.name}>
<Link
href={link.href}
className="text-gray-300 hover:text-white transition-colors duration-200"
className="text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-white transition-colors duration-200"
{...(link.href.startsWith('http') && {
target: "_blank",
rel: "noopener noreferrer"
Expand All @@ -93,13 +93,15 @@ const Footer: React.FC = () => {

{/* Resources Links */}
<div>
<h3 className="font-semibold text-white mb-4">Resources</h3>
<h3 className="font-semibold text-gray-900 dark:text-white mb-4">Resources</h3>
<ul className="space-y-2">
{footerLinks.resources.map((link) => (
<li key={link.name}>
<Link
href={link.href}
className="text-gray-300 hover:text-white transition-colors duration-200"
className="text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-white transition-colors duration-200"
target="_blank"
rel="noopener noreferrer"
>
{link.name}
</Link>
Expand All @@ -110,13 +112,13 @@ const Footer: React.FC = () => {

{/* Open Source Links */}
<div>
<h3 className="font-semibold text-white mb-4">Open Source</h3>
<h3 className="font-semibold text-gray-900 dark:text-white mb-4">Open Source</h3>
<ul className="space-y-2">
{footerLinks.opensource.map((link) => (
<li key={link.name}>
<Link
href={link.href}
className="text-gray-300 hover:text-white transition-colors duration-200"
className="text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-white transition-colors duration-200"
target="_blank"
rel="noopener noreferrer"
>
Expand All @@ -129,15 +131,21 @@ const Footer: React.FC = () => {
</div>

{/* Bottom Section */}
<div className="border-t border-gray-800 mt-12 pt-8 flex flex-col md:flex-row justify-between items-center">
<p className="text-gray-400 text-sm">
<div className="border-t border-gray-200 dark:border-gray-800 mt-12 pt-8 flex flex-col md:flex-row justify-between items-center">
<p className="text-gray-600 dark:text-gray-400 text-sm">
© {currentYear} OpsiMate. All rights reserved.
</p>
<div className="flex space-x-6 mt-4 md:mt-0">
<Link href="/privacy" className="text-gray-400 hover:text-white text-sm transition-colors duration-200">
<Link
href="/privacy"
className="text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-white text-sm transition-colors duration-200"
>
Privacy Policy
</Link>
<Link href="/terms" className="text-gray-400 hover:text-white text-sm transition-colors duration-200">
<Link
href="/terms"
className="text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-white text-sm transition-colors duration-200"
>
Terms of Service
</Link>
</div>
Expand Down