diff --git a/src/components/About/About.css b/src/components/About/About.css index bc263fb..0a57c57 100644 --- a/src/components/About/About.css +++ b/src/components/About/About.css @@ -1,3 +1,5 @@ +/* src/components/About/About.css */ + .about-page { margin: 20px auto 20px; max-width: 450px; diff --git a/src/components/About/About.js b/src/components/About/About.js index 8ff4de8..0a1e00a 100644 --- a/src/components/About/About.js +++ b/src/components/About/About.js @@ -3,6 +3,7 @@ import React from 'react'; import './About.css'; import { Link } from 'react-router-dom'; +import RelatedPagesNav from '../common/RelatedPagesNav'; const About = () => { return ( @@ -43,10 +44,13 @@ const About = () => {

Why is cred.blue in a "beta" state?

To put it simply, cred.blue is very experimental and at this early stage things will likely change a lot. The first version of the scoring algorithm lays a foundation for future plans, but it will take some time (and real-world usage) to calibrate the model's weights and variables.

+ + {/* Add the related pages navigation */} + ); }; -export default About; +export default About; \ No newline at end of file diff --git a/src/components/Definitions/Definitions.css b/src/components/Definitions/Definitions.css index ead69a6..1f7f6c0 100644 --- a/src/components/Definitions/Definitions.css +++ b/src/components/Definitions/Definitions.css @@ -1,3 +1,5 @@ +/* src/components/Definitions/Definitions.css */ + .definitions-page { margin: 20px auto 20px; max-width: 450px; diff --git a/src/components/Definitions/Definitions.js b/src/components/Definitions/Definitions.js index ec9ea51..efc745a 100644 --- a/src/components/Definitions/Definitions.js +++ b/src/components/Definitions/Definitions.js @@ -1,6 +1,7 @@ import React, { useState } from 'react'; import './Definitions.css'; import { Link } from 'react-router-dom'; +import RelatedPagesNav from '../common/RelatedPagesNav'; const Definitions = () => { // State to track which definition is expanded @@ -225,6 +226,9 @@ const Definitions = () => { ))} + + {/* Add the related pages navigation */} + diff --git a/src/components/Navbar/Navbar.css b/src/components/Navbar/Navbar.css index e6abad4..73b8b0a 100644 --- a/src/components/Navbar/Navbar.css +++ b/src/components/Navbar/Navbar.css @@ -238,7 +238,6 @@ .dropdown-trigger { position: relative; display: inline-block; - padding-right: 20px; /* Space for the arrow indicator */ white-space: nowrap; } diff --git a/src/components/Resources/Resources.css b/src/components/Resources/Resources.css index 7db96b9..79e09e4 100644 --- a/src/components/Resources/Resources.css +++ b/src/components/Resources/Resources.css @@ -15,24 +15,31 @@ transition: background-color 0.3s ease, border-color 0.3s ease; } +/* Improved header structure */ .resources-header { - margin-bottom: 1.5rem; + margin-bottom: 2rem; } .resources-header h1 { - font-size: 1.5rem; + font-size: 2rem; font-weight: bold; - margin-bottom: 0.5rem; + margin-bottom: 1rem; color: var(--button-bg); + text-align: center; +} + +.resources-intro { + max-width: 800px; + margin: 0 auto 1.5rem auto; } .resources-page ul { list-style: none; text-align: center; - margin: 0px auto; - padding: 0px; + margin: 0 auto 1rem auto; + padding: 0; width: 100%; - opacity: 0.5; + opacity: 0.8; } .resources-description { @@ -40,15 +47,19 @@ line-height: 1.5; opacity: 0.8; transition: color 0.3s ease; - margin-top: 1rem; + text-align: center; + font-size: 1.1rem; + margin: 0 auto; } +/* Improved disclaimer styling */ .resources-disclaimer { background-color: var(--card-border); border-left: 4px solid #ffd700; padding: 12px 16px; - margin-bottom: 24px; + margin: 1.5rem auto; border-radius: 4px; + max-width: 900px; } .resources-disclaimer p { @@ -58,16 +69,17 @@ } .share-button-container { - margin-top: 1rem; + text-align: center; + margin: 1.5rem auto; } .share-button { background-color: var(--button-bg); color: var(--button-text); - padding: 10px 16px; + padding: 10px 20px; border: none; border-radius: 20px; - font-size: 0.9rem; + font-size: 0.95rem; font-weight: 600; cursor: pointer; display: inline-flex; @@ -79,8 +91,12 @@ opacity: 0.8; } +/* Improved search and filters */ .resources-filters { margin-bottom: 30px; + max-width: 900px; + margin-left: auto; + margin-right: auto; } .search-container { @@ -89,9 +105,9 @@ .search-input { width: 100%; - padding: 12px 16px; + padding: 14px 18px; font-size: 1rem; - border: 1px solid var(--card-border); + border: 2px solid var(--card-border); border-radius: 8px; box-sizing: border-box; background-color: var(--navbar-bg); @@ -102,6 +118,7 @@ .search-input:focus { border-color: var(--button-bg); outline: none; + box-shadow: 0 0 0 2px rgba(var(--button-bg-rgb), 0.2); } .filter-options { @@ -112,22 +129,26 @@ justify-content: space-between; } -/* New filter dropdowns styling */ +/* Filter dropdowns styling */ .filter-dropdowns { display: flex; gap: 16px; width: 100%; + align-items: center; +} + +.category-filter-dropdown { + flex: 2; } -.category-filter-dropdown, .quality-filter { - flex: 1; + flex: 2; } .filter-select { width: 100%; padding: 12px 16px; - border: 1px solid var(--card-border); + border: 2px solid var(--card-border); border-radius: 8px; font-size: 0.95rem; background-color: var(--navbar-bg); @@ -145,6 +166,63 @@ outline: none; } +/* New star filter styling */ +.quality-filter-stars { + display: flex; + align-items: center; + gap: 8px; + background-color: var(--navbar-bg); + border: 2px solid var(--card-border); + border-radius: 8px; + padding: 8px 12px; + height: 44px; + box-sizing: border-box; +} + +.quality-filter-label { + font-size: 0.95rem; + font-weight: 500; + color: var(--text); + margin-right: 4px; +} + +.star-filter-container { + display: flex; + align-items: center; + gap: 3px; +} + +.star-filter-container .quality-star { + cursor: pointer; + font-size: 1.4rem; + transition: transform 0.1s, color 0.2s; +} + +.star-filter-container .quality-star:hover { + transform: scale(1.1); +} + +.star-filter-container .quality-star.filled { + color: #ffd700; +} + +.star-filter-container .quality-star.empty { + color: var(--card-border); +} + +.quality-filter-clear { + font-size: 0.8rem; + margin-left: 5px; + cursor: pointer; + color: var(--text); + opacity: 0.7; + font-weight: bold; +} + +.quality-filter-clear:hover { + opacity: 1; +} + .featured-section, .all-resources-section { margin-bottom: 40px; @@ -159,7 +237,7 @@ padding-bottom: 8px; } -/* New category section styling */ +/* Category section styling */ .category-section { margin-bottom: 30px; } @@ -213,10 +291,46 @@ flex-direction: column; } +/* Improved resource header styling */ +.resource-header { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 10px; +} + .resource-name { font-size: 1.1rem; - margin: 0 0 8px 0; + margin: 0; color: var(--button-bg); + line-height: 1.3; +} + +/* Improved NEW badge styling */ +.new-badge { + background-color: var(--button-bg); + color: var(--button-text); + padding: 2px 8px; + border-radius: 12px; + font-size: 0.7rem; + font-weight: bold; + display: inline-flex; + align-items: center; + height: 18px; + vertical-align: text-top; + animation: pulse 2s infinite; +} + +@keyframes pulse { + 0% { + transform: scale(1); + } + 50% { + transform: scale(1.05); + } + 100% { + transform: scale(1); + } } .resource-description { @@ -256,8 +370,8 @@ } .quality-star { - font-size: 1.1rem; /* Increased from 0.9rem */ - margin-left: 3px; /* Increased from 2px */ + font-size: 1.1rem; + margin-left: 3px; font-weight: bold; text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.1); } @@ -303,46 +417,12 @@ opacity: 0.8; } -/* Add these styles to your existing Resources.css file */ - -/* New badge styling */ -.new-badge { - background-color: #007aff; - color: white; - padding: 2px 8px; - border-radius: 12px; - font-size: 0.7rem; - font-weight: bold; - margin-left: 8px; - display: inline-block; - vertical-align: middle; - animation: pulse 2s infinite; -} - -@keyframes pulse { - 0% { - transform: scale(1); - } - 50% { - transform: scale(1.05); - } - 100% { - transform: scale(1); - } -} - -/* Resource header to display name and new badge on same line */ -.resource-header { - display: flex; - align-items: center; - margin-bottom: 8px; -} - /* New filter toggle styling */ .new-filter { - margin-left: 15px; + flex: 1; display: flex; align-items: center; + justify-content: flex-end; } .toggle-label { @@ -357,14 +437,14 @@ position: relative; width: 40px; height: 20px; - background-color: #ddd; + background-color: var(--card-border); border-radius: 20px; transition: background-color 0.3s; cursor: pointer; } .toggle-label input[type="checkbox"]:checked { - background-color: #007aff; + background-color: var(--button-bg); } .toggle-label input[type="checkbox"]::before { @@ -393,7 +473,7 @@ .filter-options .filter-dropdowns { flex-direction: column; align-items: flex-start; - gap: 10px; + gap: 12px; } .category-filter-dropdown, @@ -405,6 +485,15 @@ .filter-select { width: 100%; } + + .new-filter { + justify-content: flex-start; + } + + .quality-filter-stars { + width: 100%; + justify-content: space-between; + } } @keyframes spin { @@ -422,6 +511,10 @@ padding: 1rem; } + .resources-header h1 { + font-size: 1.5rem; + } + .resources-header { flex-direction: column; align-items: flex-start; @@ -445,4 +538,8 @@ .resources-page { max-width: 100%; } + + .resources-header h1 { + font-size: 1.3rem; + } } \ No newline at end of file diff --git a/src/components/Resources/Resources.js b/src/components/Resources/Resources.js index 4fb5bd3..6f338bf 100644 --- a/src/components/Resources/Resources.js +++ b/src/components/Resources/Resources.js @@ -9,7 +9,7 @@ const Resources = () => { const [resources, setResources] = useState([]); const [activeCategory, setActiveCategory] = useState('All'); const [searchQuery, setSearchQuery] = useState(''); - const [qualityFilter, setQualityFilter] = useState('All'); + const [qualityFilter, setQualityFilter] = useState(0); // Changed to numeric value (0 = All) const [showNewOnly, setShowNewOnly] = useState(false); const [isLoading, setIsLoading] = useState(true); @@ -36,7 +36,7 @@ const Resources = () => { try { const preferences = JSON.parse(savedPreferences); setActiveCategory(preferences.activeCategory || 'All'); - setQualityFilter(preferences.qualityFilter || 'All'); + setQualityFilter(preferences.qualityFilter || 0); setShowNewOnly(preferences.showNewOnly || false); } catch (error) { console.error('Error loading preferences:', error); @@ -148,12 +148,10 @@ const Resources = () => { resource.description.toLowerCase().includes(searchQuery.toLowerCase()) || (resource.domain && resource.domain.toLowerCase().includes(searchQuery.toLowerCase())); - // Filter by quality + // Filter by quality (changed to numeric) const qualityMatch = - qualityFilter === 'All' || - (qualityFilter === 'High' && resource.quality >= 4) || - (qualityFilter === 'Medium' && resource.quality === 3) || - (qualityFilter === 'Low' && resource.quality <= 2); + qualityFilter === 0 || + resource.quality >= qualityFilter; // Filter by "new" status if the toggle is active const newMatch = !showNewOnly || isNewResource(resource.created_at); @@ -184,18 +182,34 @@ const Resources = () => { // Should show featured section only when All category is selected const shouldShowFeatured = activeCategory === 'All'; + // Handle star rating click for quality filter + const handleStarClick = (rating) => { + setQualityFilter(rating === qualityFilter ? 0 : rating); + }; + return ( - <> -
-
+
+

Bluesky Resources

-
    -
  • Find tools to enhance your Bluesky experience.
  • -
  • Discover analytics, feeds, clients, and more.
  • -
  • Explore community-built solutions.
  • -
-

A curated collection of third-party tools, services, and guides for the Bluesky ecosystem

+ + {/* Improved header structure */} +
+
    +
  • Find tools to enhance your Bluesky experience.
  • +
  • Discover analytics, feeds, clients, and more.
  • +
  • Explore community-built solutions.
  • +
+

+ A curated collection of third-party tools, services, and guides for the Bluesky ecosystem +

+
+ + {/* Improved disclaimer positioning */} +
+

Disclaimer: These resources are third-party tools and services not affiliated with cred.blue or Bluesky. + Use them at your own risk and exercise caution when providing access to your data.

+
-
-

Disclaimer: These resources are third-party tools and services not affiliated with cred.blue or Bluesky. - Use them at your own risk and exercise caution when providing access to your data.

-
- {isLoading ? ( ) : ( <> + {/* Improved search and filters layout */}
{
- {/* Quality filter dropdown */} + {/* New Quality Filter using Stars */}
- +
+ Quality: +
+ {[1, 2, 3, 4, 5].map((rating) => ( + handleStarClick(rating)} + className={`quality-star ${rating <= qualityFilter ? 'filled' : 'empty'}`} + title={`${rating} stars or higher`} + > + ★ + + ))} + {qualityFilter > 0 && ( + setQualityFilter(0)} + title="Clear filter" + > + ✕ + + )} +
+
{/* New resources toggle */} @@ -335,9 +359,8 @@ const Resources = () => { )} )} -
-
- +
+
); }; diff --git a/src/components/ScoringMethodology/ScoringMethodology.js b/src/components/ScoringMethodology/ScoringMethodology.js index a921266..c2b605c 100644 --- a/src/components/ScoringMethodology/ScoringMethodology.js +++ b/src/components/ScoringMethodology/ScoringMethodology.js @@ -2,19 +2,17 @@ import React from 'react'; import './ScoringMethodology.css'; import ScoreGauge from '../UserProfile/ScoreGauge'; import { Link } from 'react-router-dom'; +import RelatedPagesNav from '../common/RelatedPagesNav'; const ScoringMethodology = () => { return (

The Scoring Methodology

-
-

Your cred.blue score is generated based on two major categories...

-

1. Bluesky Data

  • Profile content (avatar, description, etc)
  • @@ -23,7 +21,6 @@ const ScoringMethodology = () => {
  • Labelers and moderation
  • etc.
-

2. AT Protocol Data

  • Personal Data Server (PDS)
  • @@ -32,11 +29,9 @@ const ScoringMethodology = () => {
  • PLC logs
  • etc.
-

Separate scores are generated for each category and then combined to produce your final cred.blue score, allowing you to easily see which major category (Bluesky vs AT Proto) has the most impact on your score.

-

Score Ranges

For Version 1 of the scoring algorithm, there is a max score of 1,000 points. This may change in the future, or it could theoretically even be scaled down depending on feedback and usage. @@ -44,7 +39,6 @@ const ScoringMethodology = () => {

A score between 0-300 likely indicates that an account is either very new to the network or isn't very active. A score of 300-700 is within a "healthy" range. Scores that are 700+ typically indicate accounts that have been around awhile and are very active. The different score ranges are still in early development along with the algorithm, so these details are likely to change.

-

How do I increase my score?

The scoring methodology is fairly complex and not all of the variables can be easily changed (for instance, an account's age), but there are some specific actions you can take that can help give you a boost: @@ -62,15 +56,9 @@ const ScoringMethodology = () => {

This is not an exhaustive list by any means, but it should get you started. The goal of the cred.blue score isn't to attempt to max it out... rather, the point is to foster healthy behavior and activity that benefits the entire community.

- -
-

- Looking for explanations of terms used in cred.blue or details about social statuses? -

- - View Definitions & Social Status Details → - -
+ + {/* Replace the old definitions link with the new RelatedPagesNav component */} +
); diff --git a/src/components/common/RelatedPagesNav.jsx b/src/components/common/RelatedPagesNav.jsx new file mode 100644 index 0000000..51f75a8 --- /dev/null +++ b/src/components/common/RelatedPagesNav.jsx @@ -0,0 +1,51 @@ +// src/components/common/RelatedPagesNav.jsx + +import React from 'react'; +import { Link } from 'react-router-dom'; +import './RelatedPagesNav.css'; + +const RelatedPagesNav = ({ currentPage }) => { + // Define the pages and their properties + const pages = [ + { + id: "about", + path: "/about", + title: "About cred.blue", + description: "Learn what cred.blue is and why it was created" + }, + { + id: "methodology", + path: "/methodology", + title: "Scoring Methodology", + description: "Understand how the scoring algorithm works" + }, + { + id: "definitions", + path: "/definitions", + title: "Definitions & Terms", + description: "Explore key terms and social status details" + } + ]; + + // Filter out the current page + const otherPages = pages.filter(page => page.id !== currentPage); + + return ( +
+

Related Pages

+
+ {otherPages.map(page => ( + +
+

{page.title}

+

{page.description}

+
+ → + + ))} +
+
+ ); +}; + +export default RelatedPagesNav; \ No newline at end of file