Skip to content
Open
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
102 changes: 102 additions & 0 deletions src/components/DailyCodingTip.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
.container {
background: var(--ifm-card-background-color, #ffffff);
border: 1px solid var(--ifm-color-emphasis-200, #e5e7eb);
border-radius: 12px;
padding: 24px;
max-width: 600px;
margin: 24px auto;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
transition: box-shadow 0.2s ease;
}

.container:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}

.header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 16px;
}

.headerIcon {
font-size: 20px;
}

.headerTitle {
font-size: 18px;
font-weight: 700;
margin: 0;
color: var(--ifm-heading-color);
}

.tipCard {
background: var(--ifm-color-emphasis-100, #f9fafb);
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
}

.fadeIn {
animation: fadeInUp 0.3s ease forwards;
}

@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

.categoryBadge {
display: inline-block;
font-size: 11px;
font-weight: 600;
padding: 3px 10px;
border-radius: 999px;
border: 1px solid;
margin-bottom: 10px;
text-transform: uppercase;
letter-spacing: 0.05em;
}

.tipText {
font-size: 15px;
line-height: 1.6;
color: var(--ifm-font-color-base);
margin: 0;
}

.refreshButton {
background: var(--ifm-color-primary, #2563eb);
color: #ffffff;
border: none;
border-radius: 8px;
padding: 10px 20px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: opacity 0.2s ease, transform 0.1s ease;
width: 100%;
}

.refreshButton:hover {
opacity: 0.9;
transform: translateY(-1px);
}

.refreshButton:active {
transform: translateY(0);
}

@media (max-width: 768px) {
.container {
margin: 16px;
padding: 16px;
}
}
85 changes: 85 additions & 0 deletions src/components/DailyCodingTip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { useState, useEffect } from "react";
import styles from "./DailyCodingTip.module.css";
import codingTips from "../data/codingTips.json";

type Tip = {
id: number;
category: string;
tip: string;
};

const CATEGORY_COLORS: Record<string, string> = {
"Git & GitHub Tips": "#f97316",
"JavaScript/React Tips": "#3b82f6",
"Open Source Contribution Tips": "#10b981",
"VS Code Shortcuts": "#8b5cf6",
"Productivity Tricks": "#ec4899",
};

function getTipOfTheDay(): Tip {
try {
const stored = localStorage.getItem("dailyCodingTip");
const today = new Date().toDateString();
if (stored) {
const parsed = JSON.parse(stored);
if (parsed.date === today) return parsed.tip;
}
const randomTip = codingTips[Math.floor(Math.random() * codingTips.length)] as Tip;
localStorage.setItem("dailyCodingTip", JSON.stringify({ date: today, tip: randomTip }));
return randomTip;
} catch {
return codingTips[0] as Tip;
}
}

export default function DailyCodingTip(): React.ReactElement {
const [tip, setTip] = useState<Tip | null>(null);
const [animate, setAnimate] = useState(false);

useEffect(() => {
setTip(getTipOfTheDay());
setAnimate(true);
}, []);

const handleRefresh = () => {
const randomTip = codingTips[Math.floor(Math.random() * codingTips.length)] as Tip;
setAnimate(false);
setTimeout(() => {
setTip(randomTip);
setAnimate(true);
}, 150);
};

if (!tip) return <></>;

const categoryColor = CATEGORY_COLORS[tip.category] || "#6b7280";

return (
<div className={styles.container}>
<div className={styles.header}>
<span className={styles.headerIcon}>πŸ’‘</span>
<h3 className={styles.headerTitle}>Daily Coding Tip</h3>
</div>
<div className={`${styles.tipCard} ${animate ? styles.fadeIn : ""}`}>
<span
className={styles.categoryBadge}
style={{
backgroundColor: `${categoryColor}20`,
color: categoryColor,
borderColor: `${categoryColor}40`,
}}
>
{tip.category}
</span>
<p className={styles.tipText}>{tip.tip}</p>
</div>
<button
className={styles.refreshButton}
onClick={handleRefresh}
aria-label="Get a new random coding tip"
>
πŸ”€ Get Another Tip
</button>
</div>
);
}
16 changes: 11 additions & 5 deletions src/components/dashboard/LeaderBoard/leaderboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import BadgeModal from "./BadgeModal";
import { mockContributors } from "./mockData";
import "./leaderboard.css";
import DailyCodingTip from "@site/src/components/DailyCodingTip";

const GITHUB_ORG = "recodehive";

Expand Down Expand Up @@ -44,7 +45,7 @@
badges?: string[]; // Array of badge image paths
}

interface Stats {

Check warning on line 48 in src/components/dashboard/LeaderBoard/leaderboard.tsx

View workflow job for this annotation

GitHub Actions / lint

'Stats' is defined but never used
flooredTotalPRs: number;
totalContributors: number;
flooredTotalPoints: number;
Expand Down Expand Up @@ -212,7 +213,7 @@
);
}

function TopPerformerCard({

Check warning on line 216 in src/components/dashboard/LeaderBoard/leaderboard.tsx

View workflow job for this annotation

GitHub Actions / lint

'TopPerformerCard' is defined but never used
contributor,
rank,
onPRClick,
Expand Down Expand Up @@ -347,7 +348,7 @@
const paginate = (pageNumber: number) =>
setCurrentPage(Math.max(1, Math.min(pageNumber, totalPages)));

const renderPaginationButtons = () => {

Check warning on line 351 in src/components/dashboard/LeaderBoard/leaderboard.tsx

View workflow job for this annotation

GitHub Actions / lint

'maxVisibleButtons' is assigned a value but never used
const pages = [];
const maxVisibleButtons = 5; // Maximum number of page buttons to show directly

Expand Down Expand Up @@ -447,7 +448,7 @@
if (index === 2) return "top-3";
return "regular";
};

Check warning on line 451 in src/components/dashboard/LeaderBoard/leaderboard.tsx

View workflow job for this annotation

GitHub Actions / lint

'getTimeFilterLabel' is assigned a value but never used
// Helper function for time filter display
const getTimeFilterLabel = (filter: string) => {
switch (filter) {
Expand All @@ -474,11 +475,16 @@
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<h1 className="title">Recode Hive Leaderboard</h1>
<p className={`subtitle ${isDark ? "dark" : "light"}`}>
Top contributors across the <strong>{GITHUB_ORG}</strong>{" "}
organization
</p>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
<div>
<h1 className="title">Recode Hive Leaderboard</h1>
<p className={`subtitle ${isDark ? "dark" : "light"}`}>
Top contributors across the <strong>{GITHUB_ORG}</strong>{" "}
organization
</p>
</div>
<DailyCodingTip />
</div>
</motion.div>

{/* Top 3 Performers Section */}
Expand All @@ -496,7 +502,7 @@
<select
id="time-period-filter"
value={currentTimeFilter}
onChange={(e) => {

Check warning on line 505 in src/components/dashboard/LeaderBoard/leaderboard.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
// Use setTimeFilter from context
setTimeFilter(e.target.value as any);
setCurrentPage(1);
Expand Down
22 changes: 22 additions & 0 deletions src/data/codingTips.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{ "id": 1, "category": "Git & GitHub Tips", "tip": "Use `git stash` to temporarily save uncommitted changes before switching branches." },
{ "id": 2, "category": "Git & GitHub Tips", "tip": "Use `git log --oneline` for a compact view of your commit history." },
{ "id": 3, "category": "Git & GitHub Tips", "tip": "Always write meaningful commit messages β€” future you will thank present you." },
{ "id": 4, "category": "Git & GitHub Tips", "tip": "Use `git bisect` to find the commit that introduced a bug using binary search." },
{ "id": 5, "category": "JavaScript/React Tips", "tip": "Use optional chaining (`?.`) to safely access deeply nested object properties." },
{ "id": 6, "category": "JavaScript/React Tips", "tip": "Prefer `const` over `let` when the variable won't be reassigned." },
{ "id": 7, "category": "JavaScript/React Tips", "tip": "Use React.memo() to prevent unnecessary re-renders of functional components." },
{ "id": 8, "category": "JavaScript/React Tips", "tip": "Use the nullish coalescing operator (`??`) instead of `||` when 0 or empty string are valid values." },
{ "id": 9, "category": "Open Source Contribution Tips", "tip": "Always read CONTRIBUTING.md before opening a pull request." },
{ "id": 10, "category": "Open Source Contribution Tips", "tip": "Start with 'good first issue' labeled issues when contributing to a new project." },
{ "id": 11, "category": "Open Source Contribution Tips", "tip": "Keep your PRs small and focused β€” one feature or fix per PR." },
{ "id": 12, "category": "Open Source Contribution Tips", "tip": "Sync your fork with the upstream repo regularly to avoid merge conflicts." },
{ "id": 13, "category": "VS Code Shortcuts", "tip": "Use `Ctrl + P` to quickly open any file in your project." },
{ "id": 14, "category": "VS Code Shortcuts", "tip": "Use `Ctrl + Shift + K` to delete an entire line instantly." },
{ "id": 15, "category": "VS Code Shortcuts", "tip": "Use `Alt + Click` to place multiple cursors for simultaneous editing." },
{ "id": 16, "category": "VS Code Shortcuts", "tip": "Use `Ctrl + backtick` to toggle the integrated terminal." },
{ "id": 17, "category": "Productivity Tricks", "tip": "Use the Pomodoro technique β€” 25 minutes of focused work followed by a 5-minute break." },
{ "id": 18, "category": "Productivity Tricks", "tip": "Rubber duck debugging: explain your code out loud to find bugs faster." },
{ "id": 19, "category": "Productivity Tricks", "tip": "Write TODO comments in code to track unfinished work." },
{ "id": 20, "category": "Productivity Tricks", "tip": "Take breaks β€” stepping away from a problem often leads to the solution faster." }
]
5 changes: 5 additions & 0 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { TestimonialCarousel } from "../components/testimonials/TestimonialCarou
import { CommunityStatsProvider } from "../lib/statsProvider";
import { LandingCommunity } from "../components/Community";
import FAQs from "../components/faqs/faqs";
import DailyCodingTip from "../components/DailyCodingTip";

export default function Home(): ReactNode {
const { siteConfig } = useDocusaurusContext();
Expand Down Expand Up @@ -68,6 +69,10 @@ export default function Home(): ReactNode {
<Header />
</div>

<div className="m-4">
<DailyCodingTip />
</div>

<div className="blog-carousel-section">
<BlogCarousel />
</div>
Expand Down
Loading