Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Create FeaturedTopic and FeaturedTopicsRow Components #2237

Open
wants to merge 11 commits into
base: topic-landing
Choose a base branch
from
Open
2 changes: 2 additions & 0 deletions django_topics/admin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django.contrib import admin, messages
from django_topics.models import Topic, TopicPool, FeaturedTopicEnglish, FeaturedTopicHebrew, SeasonalTopicEnglish, SeasonalTopicHebrew
from django_topics.models.pool import PoolType
from django.utils.html import format_html



def create_add_to_pool_action(pool_name):
Expand Down
40 changes: 40 additions & 0 deletions static/css/s2.css
Original file line number Diff line number Diff line change
Expand Up @@ -5218,6 +5218,46 @@ h1.topic-landing-header {
.topic-landing-parasha .navSidebarLink span{
font-family: Roboto, sans-serif;
}
.topic-card-with-description-row{
display: flex;
margin-top: 30px;
gap: 20px;
}
.topic-card-with-description .card{
flex: 1;
border-top: 4px solid var(--sefaria-blue);
background: var(--lightest-grey);
box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
width: 268.395px;
height: 345.78px;
}
.topic-card-with-description .cardDescription{
margin-inline-end: 30px;
margin-inline-start: 30px;
margin-top: 19px;
Copy link
Contributor

Choose a reason for hiding this comment

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

these numbers for width and height seem pretty random, also on top seems like there are very specific numbers. ideally the cards wont have a strict width and height but rather a min-width min-height. Sefaria in general tries to stick to multiples of 5 for margins and width/height

width: 207.593px;
Copy link
Contributor

Choose a reason for hiding this comment

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

why a decimal point?

display: -webkit-box;
-webkit-box-orient: vertical;
overflow-y: hidden;
word-wrap: break-word;
}
.topic-card-with-description .cardTitle {
margin-top: 23px;
}
.topic-card-with-description .bottomCardLink {
font-size: 14px;
line-height: 18px;
color: #666;
margin-inline-end: 20px;
--english-font: var(--english-sans-serif-font-family);
--hebrew-font: var(--hebrew-sans-serif-font-family);
position: absolute;
bottom: 41px;
margin-inline-start: 30px;
}
.topic-card-with-description .cardTitle {
margin-inline-start: 30px;
}
.readerNavMenu .sheet {
display: flex;
justify-content: space-between;
Expand Down
57 changes: 57 additions & 0 deletions static/js/TopicLandingPage/RandomTopicCardWithDescriptionRow.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react';
import {useEffect, useState} from "react";
import Sefaria from "../sefaria/sefaria";
import {InterfaceText} from "../Misc";
import {Card} from "../common/Card";


export const RandomTopicCardWithDescriptionRow = () => {
const numTopics = 3;
const [deck, setDeck] = useState([]);

const renderSaladItem = (item) => {
return(<a href={`/topics/${item.slug}`} className="topic-salad-item">
<InterfaceText text={item.text}/>
</a>)
}

const fetchRandomTopicDeck = async () => {
const poolName = Sefaria.getLangSpecificTopicPoolName('general');
const topics = await Sefaria.getTopicsByPool(poolName, Math.pow(numTopics, 3));
Copy link
Contributor

Choose a reason for hiding this comment

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

can you explain why x^3?

const lang = Sefaria.interfaceLang == "hebrew"? 'he' : 'en';
const deck = topics
.filter(topic => topic.description?.[lang])
.slice(0, numTopics)
.map(topic => ({
slug: topic.slug,
title: topic.primaryTitle,
description: topic.description
}));
return deck;
}

const loadDeck = async () => {
const deck = await fetchRandomTopicDeck();
setDeck(deck);
};

useEffect(() => {
loadDeck();
}, []);

return (
<>
<div className='topic-card-with-description-row'>
{deck.map(topic=><div className='topic-card-with-description'>
<Card
cardTitleHref={`topics/${topic.slug}`}
cardTitle={topic.title}
cardText={topic.description}
bottomLinkText = {{en: `Explore ${topic.title?.en} ›`, he:`${Sefaria._("Explore")} ${topic.title?.he} ›`}}
bottomLinkUrl = {`topics/${topic.slug}`}/>
</div>)}
</div>
</>

);
};
4 changes: 4 additions & 0 deletions static/js/TopicLandingPage/TopicsLandingPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {TopicLandingSeasonal} from "./TopicLandingSeasonal";
import {TopicLandingNewsletter} from "./TopicLandingNewsletter";
import {InterfaceText} from "../Misc";
import Sefaria from "../sefaria/sefaria";
import {RandomTopicCardWithDescriptionRow} from "./RandomTopicCardWithDescriptionRow";


export const TopicsLandingPage = ({openTopic}) => {
Expand All @@ -34,6 +35,9 @@ export const TopicsLandingPage = ({openTopic}) => {
<div className="topic-landing-section">
<TopicLandingNewsletter />
</div>
<div className="topic-landing-section">
<RandomTopicCardWithDescriptionRow/>
</div>
<div className="topic-landing-section topic-landing-temporal">
<TopicLandingParasha/>
<TopicLandingSeasonal/>
Expand Down
15 changes: 11 additions & 4 deletions static/js/common/Card.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import {InterfaceText} from "../Misc";
import React from "react";
const Card = ({cardTitle, cardTitleHref, oncardTitleClick, cardText}) => {
const Card = ({cardTitle, cardTitleHref, oncardTitleClick, cardText, bottomLinkText, bottomLinkUrl}) => {
return <div className="card">
<a href={cardTitleHref} className="cardTitle" onClick={oncardTitleClick}>
<InterfaceText text={cardTitle}/>
</a>
<div className="cardDescription">
<InterfaceText text={cardText}/>
<InterfaceText markdown={cardText}/>
</div>
{bottomLinkText &&
<div className="bottomCardLink">
<a href={bottomLinkUrl}>
<InterfaceText text={bottomLinkText}/>
</a>
</div>
}
</div>
}
}

export { Card }
export {Card}
Loading