Merge branch 'main' into threaded-free-response-comments

This commit is contained in:
Boa 2022-05-03 08:52:48 -06:00 committed by GitHub
commit 63bf7649b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 228 additions and 133 deletions

View File

@ -172,7 +172,7 @@ export function calculateCpmmSale(
shares: number, shares: number,
outcome: string outcome: string
) { ) {
if (shares < 0) { if (Math.round(shares) < 0) {
throw new Error('Cannot sell non-positive shares') throw new Error('Cannot sell non-positive shares')
} }

View File

@ -19,8 +19,7 @@ export const charities: Charity[] = [
website: 'https://www.1daysooner.org/', website: 'https://www.1daysooner.org/',
preview: preview:
'Accelerating the development of each vaccine by even a couple of days via COVID-19 human challenge trials could save thousands of lives.', 'Accelerating the development of each vaccine by even a couple of days via COVID-19 human challenge trials could save thousands of lives.',
photo: photo: 'https://i.imgur.com/bUDdzUE.png',
'https://images.squarespace-cdn.com/content/v1/5f5f8496d1d7713486b6075a/666cbb5a-5335-4323-b9ea-b764edc826e1/OFFICIAL+1Day+Sooner+Logo.png',
description: `1Day Sooner is a non-profit that advocates on behalf of COVID-19 challenge trial volunteers. description: `1Day Sooner is a non-profit that advocates on behalf of COVID-19 challenge trial volunteers.
After a vaccine candidate is created in a lab, it is developed through a combination of pre-clinical evaluation and three phases of clinical trials that test its safety and efficacy. In traditional Phase III trials, participants receive the vaccine candidate or a placebo/active comparator, and efficacy is judged by comparing the prevalence of infection in the vaccine group and the placebo/comparator group, to test the hypothesis that significantly fewer participants in the vaccine group get infected. In these traditional trials, after receiving the treatment, participants return to their homes and their normal daily lives so as to test the treatment under real world conditions. Since only a small proportion of these participants may encounter the disease, it may take a large number of participants and a good deal of time for these trials to reveal differences between the vaccine and placebo groups. After a vaccine candidate is created in a lab, it is developed through a combination of pre-clinical evaluation and three phases of clinical trials that test its safety and efficacy. In traditional Phase III trials, participants receive the vaccine candidate or a placebo/active comparator, and efficacy is judged by comparing the prevalence of infection in the vaccine group and the placebo/comparator group, to test the hypothesis that significantly fewer participants in the vaccine group get infected. In these traditional trials, after receiving the treatment, participants return to their homes and their normal daily lives so as to test the treatment under real world conditions. Since only a small proportion of these participants may encounter the disease, it may take a large number of participants and a good deal of time for these trials to reveal differences between the vaccine and placebo groups.
@ -35,8 +34,7 @@ export const charities: Charity[] = [
website: 'https://quantifieduncertainty.org/', website: 'https://quantifieduncertainty.org/',
preview: preview:
'The Quantified Uncertainty Research Institute advances forecasting and epistemics to improve the long-term future of humanity.', 'The Quantified Uncertainty Research Institute advances forecasting and epistemics to improve the long-term future of humanity.',
photo: photo: 'https://i.imgur.com/ZsSXPjH.png',
'https://quantifieduncertainty.org/_next/image?url=https%3A%2F%2Fsuper-static-assets.s3.amazonaws.com%2F09bb1362-5e3f-4724-8ffd-f3235f67356f%2Fimages%2F6151ac3e-aed7-44c7-9827-399fe6e9222b.png&w=1920&q=80',
description: `QURI researches systematic practices to specify and estimate the most important parameters for the most important or scalable decisions. Research areas include forecasting, epistemics, evaluations, ontology, and estimation. description: `QURI researches systematic practices to specify and estimate the most important parameters for the most important or scalable decisions. Research areas include forecasting, epistemics, evaluations, ontology, and estimation.
We emphasize technological solutions that can heavily scale in the next 5 to 30 years. We emphasize technological solutions that can heavily scale in the next 5 to 30 years.
@ -47,7 +45,7 @@ export const charities: Charity[] = [
{ {
name: 'Long-Term Future Fund', name: 'Long-Term Future Fund',
website: 'https://funds.effectivealtruism.org/funds/far-future', website: 'https://funds.effectivealtruism.org/funds/far-future',
photo: 'https://app.effectivealtruism.org/logo-funds.svg', photo: 'https://i.imgur.com/C2qka9g.png',
preview: preview:
'Positively influence the long-term trajectory of civilization by making grants that address global catastrophic risks.', 'Positively influence the long-term trajectory of civilization by making grants that address global catastrophic risks.',
description: `The Fund has a broad remit to make grants that promote, implement and advocate for longtermist ideas. Many of our grants aim to address potential risks from advanced artificial intelligence and to build infrastructure and advocate for longtermist projects. However, we welcome applications related to long-term institutional reform or other global catastrophic risks (e.g., pandemics or nuclear conflict). description: `The Fund has a broad remit to make grants that promote, implement and advocate for longtermist ideas. Many of our grants aim to address potential risks from advanced artificial intelligence and to build infrastructure and advocate for longtermist projects. However, we welcome applications related to long-term institutional reform or other global catastrophic risks (e.g., pandemics or nuclear conflict).
@ -61,7 +59,7 @@ export const charities: Charity[] = [
{ {
name: 'GiveWell Maximum Impact Fund', name: 'GiveWell Maximum Impact Fund',
website: 'https://www.givewell.org/maximum-impact-fund', website: 'https://www.givewell.org/maximum-impact-fund',
photo: 'https://www.givewell.org/sites/all/themes/gw_basic/logo.png', photo: 'https://i.imgur.com/xikuDMZ.png',
preview: preview:
'We search for the charities that save or improve lives the most per dollar.', 'We search for the charities that save or improve lives the most per dollar.',
description: ` description: `
@ -98,8 +96,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Give Directly', name: 'Give Directly',
website: 'https://www.givedirectly.org/', website: 'https://www.givedirectly.org/',
ein: '27-1661997', ein: '27-1661997',
photo: photo: 'https://i.imgur.com/lrdxSyd.jpg',
'https://www.givewell.org/sites/default/files/charity_logos/GiveDirectly.jpg',
preview: 'Send money directly to people living in poverty.', preview: 'Send money directly to people living in poverty.',
description: description:
'GiveDirectly is a nonprofit that lets donors like you send money directly to the worlds poorest households. We believe people living in poverty deserve the dignity to choose for themselves how best to improve their lives — cash enables that choice. Since 2009, weve delivered $500M+ in cash directly into the hands of over 1 million families living in poverty. We currently have operations in Kenya, Rwanda, Liberia, Malawi, Morocco, Mozambique, DRC, Uganda, and the United States.', 'GiveDirectly is a nonprofit that lets donors like you send money directly to the worlds poorest households. We believe people living in poverty deserve the dignity to choose for themselves how best to improve their lives — cash enables that choice. Since 2009, weve delivered $500M+ in cash directly into the hands of over 1 million families living in poverty. We currently have operations in Kenya, Rwanda, Liberia, Malawi, Morocco, Mozambique, DRC, Uganda, and the United States.',
@ -108,8 +105,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Hellen Keller International', name: 'Hellen Keller International',
website: 'https://www.hki.org/', website: 'https://www.hki.org/',
ein: '13-5562162', ein: '13-5562162',
photo: photo: 'https://i.imgur.com/Dl97Abk.jpg',
'https://www.ntd-ngonetwork.org/sites/nnn/files/content/organisation/logos/2020-01-28/v2_HKLogo_Primary_RGB.jpg',
preview: preview:
'We envision a world where no one is deprived of the opportunity to live a healthy life and reach their true potential.', 'We envision a world where no one is deprived of the opportunity to live a healthy life and reach their true potential.',
description: description:
@ -119,8 +115,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Against Malaria Foundation', name: 'Against Malaria Foundation',
website: 'https://www.againstmalaria.com/', website: 'https://www.againstmalaria.com/',
ein: '20-3069841', ein: '20-3069841',
photo: photo: 'https://i.imgur.com/F3JoZi9.png',
'https://media-exp1.licdn.com/dms/image/C4D0BAQFvdcum9KBNfg/company-logo_200_200/0?e=2159024400&v=beta&t=hxjJCKQkMp2irTOcuJEceW7x4l3c4PD7gYCQ6ulgYlg',
preview: 'We help protect people from malaria.', preview: 'We help protect people from malaria.',
description: description:
'AMF (againstmalaria.com) provides funding for long-lasting insecticide-treated net (LLIN) distributions (for protection against malaria) in developing countries. There is strong evidence that distributing LLINs reduces child mortality and malaria cases. AMF conducts post-distribution surveys of completed distributions to determine whether LLINs have reached their intended destinations and how long they remain in good condition.', 'AMF (againstmalaria.com) provides funding for long-lasting insecticide-treated net (LLIN) distributions (for protection against malaria) in developing countries. There is strong evidence that distributing LLINs reduces child mortality and malaria cases. AMF conducts post-distribution surveys of completed distributions to determine whether LLINs have reached their intended destinations and how long they remain in good condition.',
@ -128,8 +123,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
{ {
name: 'Rethink Charity', name: 'Rethink Charity',
website: 'https://rethink.charity/', website: 'https://rethink.charity/',
photo: photo: 'https://i.imgur.com/Go7N7As.png',
'https://process.filestackapi.com/resize=width:600,height:315,fit:max/quality=value:90/jvYvq1JFQkOqo3J8hVcJ',
preview: preview:
'Providing vital support to high-impact charities and charitable projects.', 'Providing vital support to high-impact charities and charitable projects.',
description: `At Rethink Charity, were excited about improving the world by providing vital support to high-impact charities and charitable projects. We equip them with tools to boost their impact, through our projects that empower their donors with tax-efficient giving options and strategically coordinated matching opportunities. description: `At Rethink Charity, were excited about improving the world by providing vital support to high-impact charities and charitable projects. We equip them with tools to boost their impact, through our projects that empower their donors with tax-efficient giving options and strategically coordinated matching opportunities.
@ -143,8 +137,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Malaria Consortium', name: 'Malaria Consortium',
website: 'https://www.malariaconsortium.org/', website: 'https://www.malariaconsortium.org/',
ein: '98-0627052', ein: '98-0627052',
photo: photo: 'https://i.imgur.com/LGwy9d8.png ',
'https://www.malariaconsortium.org/website-2013/images_template/malaria_consortium_logo.png',
preview: preview:
'We specialise in the prevention, control and treatment of malaria and other communicable diseases.', 'We specialise in the prevention, control and treatment of malaria and other communicable diseases.',
description: description:
@ -153,7 +146,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
{ {
name: 'The Center for the Study of Partisanship and Ideology', name: 'The Center for the Study of Partisanship and Ideology',
website: 'https://cspicenter.org/', website: 'https://cspicenter.org/',
photo: 'https://cspicenter.org/wp-content/uploads/2020/02/CSPI.png', photo: 'https://i.imgur.com/O88tkOW.png',
preview: preview:
'Support and fund research on how ideology and government policy contribute to scientific, technological, and social progress.', 'Support and fund research on how ideology and government policy contribute to scientific, technological, and social progress.',
description: `Over the last few decades, scientific and technological progress have stagnated. Scientists conduct more research than ever before, but groundbreaking innovation is scarce. At the same time, identity politics and political polarization have reached new extremes, and social trends such as family stability and crime are worse than in previous decades and in some cases moving in the wrong direction. What explains these trends, and how can we reverse them? description: `Over the last few decades, scientific and technological progress have stagnated. Scientists conduct more research than ever before, but groundbreaking innovation is scarce. At the same time, identity politics and political polarization have reached new extremes, and social trends such as family stability and crime are worse than in previous decades and in some cases moving in the wrong direction. What explains these trends, and how can we reverse them?
@ -170,8 +163,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Faunalytics', name: 'Faunalytics',
website: 'https://faunalytics.org/', website: 'https://faunalytics.org/',
ein: '01-0686889', ein: '01-0686889',
photo: photo: 'https://i.imgur.com/3JXhuXl.jpg',
'https://animalcharityevaluators.org/wp-content/uploads/2016/08/logo-faunalytics2400x2400-200x200@2x.jpg',
preview: preview:
'Faunalytics conducts research and shares knowledge to help advocates help animals effectively.', 'Faunalytics conducts research and shares knowledge to help advocates help animals effectively.',
description: description:
@ -181,8 +173,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'The Humane League', name: 'The Humane League',
website: 'https://thehumaneleague.org/', website: 'https://thehumaneleague.org/',
ein: '04-3817491', ein: '04-3817491',
photo: photo: 'https://i.imgur.com/za9Rwon.jpg',
'https://animalcharityevaluators.org/wp-content/uploads/2019/03/thl-mended-heart-logo@2x-200x200@2x.jpg',
preview: preview:
'We exist to end the abuse of animals raised for food by influencing the policies of the worlds biggest companies, demanding legislation, and empowering others to take action and leave animals off their plates', 'We exist to end the abuse of animals raised for food by influencing the policies of the worlds biggest companies, demanding legislation, and empowering others to take action and leave animals off their plates',
description: description:
@ -192,8 +183,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Wild Animal Initiative', name: 'Wild Animal Initiative',
website: 'https://www.wildanimalinitiative.org/', website: 'https://www.wildanimalinitiative.org/',
ein: '82-2281466', ein: '82-2281466',
photo: photo: 'https://i.imgur.com/bOVUnDm.png',
'https://animalcharityevaluators.org/wp-content/uploads/2020/11/WAI-logo_square-gray-on-teal-1-630x630.png',
preview: 'We want to make life better for wild animals.', preview: 'We want to make life better for wild animals.',
description: description:
'Wild Animal Initiative (WAI) currently operates in the U.S., where they work to strengthen the animal advocacy movement through creating an academic field dedicated to wild animal welfare. They compile literature reviews, write theoretical and opinion articles, and publish research results on their website and/or in peer-reviewed journals. WAI focuses on identifying and sharing possible research avenues and connecting with more established fields. They also work with researchers from various academic and non-academic institutions to identify potential collaborators, and they recently launched a grant assistance program.', 'Wild Animal Initiative (WAI) currently operates in the U.S., where they work to strengthen the animal advocacy movement through creating an academic field dedicated to wild animal welfare. They compile literature reviews, write theoretical and opinion articles, and publish research results on their website and/or in peer-reviewed journals. WAI focuses on identifying and sharing possible research avenues and connecting with more established fields. They also work with researchers from various academic and non-academic institutions to identify potential collaborators, and they recently launched a grant assistance program.',
@ -202,8 +192,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'New Incentives', name: 'New Incentives',
website: 'https://www.newincentives.org/', website: 'https://www.newincentives.org/',
ein: '45-2368993', ein: '45-2368993',
photo: photo: 'https://i.imgur.com/bYl4tk3.png',
'https://uploads-ssl.webflow.com/5f7c51bf9fac9b5ed62aa37b/5f7c51bf9fac9b85c42aa3df_Group%20344%20(1).svg',
preview: 'Cash incentives to boost vaccination rates and save lives.', preview: 'Cash incentives to boost vaccination rates and save lives.',
description: description:
'New Incentives (newincentives.org) runs a conditional cash transfer (CCT) program in North West Nigeria which seeks to increase uptake of routine immunizations through cash transfers, raising public awareness of the benefits of vaccination and reducing the frequency of vaccine stockouts.', 'New Incentives (newincentives.org) runs a conditional cash transfer (CCT) program in North West Nigeria which seeks to increase uptake of routine immunizations through cash transfers, raising public awareness of the benefits of vaccination and reducing the frequency of vaccine stockouts.',
@ -212,8 +201,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'SCI foundation', name: 'SCI foundation',
website: 'https://schistosomiasiscontrolinitiative.org/', website: 'https://schistosomiasiscontrolinitiative.org/',
ein: '', ein: '',
photo: photo: 'https://i.imgur.com/sWD8zM5.png',
'https://images.easyfundraising.org.uk/cause/cropped/cause-logo-e99e0632a8a9572150fdcf3abf08ad45.png',
preview: preview:
'SCI works with governments in sub-Saharan Africa to create or scale up programs that treat schistosomiasis and soil-transmitted helminthiasis ("deworming").', 'SCI works with governments in sub-Saharan Africa to create or scale up programs that treat schistosomiasis and soil-transmitted helminthiasis ("deworming").',
description: description:
@ -223,8 +211,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Wikimedia Foundation', name: 'Wikimedia Foundation',
website: 'https://wikimediafoundation.org/', website: 'https://wikimediafoundation.org/',
ein: '20-0049703', ein: '20-0049703',
photo: photo: 'https://i.imgur.com/klEzUbR.png',
'https://2.bp.blogspot.com/-jVseU39DW0s/VjmXVMOEEEI/AAAAAAAACK8/dwUP6sLqy-Q/s1600/wikimedia.png',
preview: 'We help everyone share in the sum of all knowledge.', preview: 'We help everyone share in the sum of all knowledge.',
description: description:
'We are the people who keep knowledge free. There is an amazing community of people around the world that makes great projects like Wikipedia. We help them do that work. We take care of the technical infrastructure, the legal challenges, and the growing pains.', 'We are the people who keep knowledge free. There is an amazing community of people around the world that makes great projects like Wikipedia. We help them do that work. We take care of the technical infrastructure, the legal challenges, and the growing pains.',
@ -233,8 +220,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Rainforest Trust', name: 'Rainforest Trust',
website: 'https://www.rainforesttrust.org/', website: 'https://www.rainforesttrust.org/',
ein: '13-3500609', ein: '13-3500609',
photo: photo: 'https://i.imgur.com/6MzS530.png',
'https://ww1.prweb.com/prfiles/2019/05/29/16344590/Rrainforest%20Trust%20new%20logo%20tall-1%20copy.png',
preview: preview:
'Rainforest Trust saves endangered wildlife and protects our planet by creating rainforest reserves through partnerships, community engagement and donor support.', 'Rainforest Trust saves endangered wildlife and protects our planet by creating rainforest reserves through partnerships, community engagement and donor support.',
description: description:
@ -244,8 +230,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'The Nature Conservancy', name: 'The Nature Conservancy',
website: 'https://www.nature.org/en-us/', website: 'https://www.nature.org/en-us/',
ein: '53-0242652', ein: '53-0242652',
photo: photo: 'https://i.imgur.com/vjxkoGo.jpg',
'https://mma.prnewswire.com/media/1140905/The_Nature_Conservancy_Logo.jpg?p=facebook',
preview: 'A Future Where People and Nature Thrive', preview: 'A Future Where People and Nature Thrive',
description: description:
'The Nature Conservancy is a global environmental nonprofit working to create a world where people and nature can thrive. Founded in the U.S. through grassroots action in 1951, The Nature Conservancy has grown to become one of the most effective and wide-reaching environmental organizations in the world. Thanks to more than a million members and the dedicated efforts of our diverse staff and over 400 scientists, we impact conservation in 76 countries and territories: 37 by direct conservation impact and 39 through partners.', 'The Nature Conservancy is a global environmental nonprofit working to create a world where people and nature can thrive. Founded in the U.S. through grassroots action in 1951, The Nature Conservancy has grown to become one of the most effective and wide-reaching environmental organizations in the world. Thanks to more than a million members and the dedicated efforts of our diverse staff and over 400 scientists, we impact conservation in 76 countries and territories: 37 by direct conservation impact and 39 through partners.',
@ -254,7 +239,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Doctors Without Borders', name: 'Doctors Without Borders',
website: 'https://www.doctorswithoutborders.org/', website: 'https://www.doctorswithoutborders.org/',
ein: '13-3433452', ein: '13-3433452',
photo: 'https://www.doctorswithoutborders.org/themes/custom/msf/logo.svg', photo: 'https://i.imgur.com/xqhH9FE.png',
preview: preview:
'We provide independent, impartial medical humanitarian assistance to the people who need it most.', 'We provide independent, impartial medical humanitarian assistance to the people who need it most.',
description: description:
@ -264,8 +249,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'World Wildlife Fund', name: 'World Wildlife Fund',
website: 'https://www.worldwildlife.org/', website: 'https://www.worldwildlife.org/',
ein: '52-1693387', ein: '52-1693387',
photo: photo: 'https://i.imgur.com/hDADuqW.png',
'https://www.worldwildlife.org/assets/structure/unique/logo-c562409bb6158bf64e5f8b1be066dbd5983d75f5ce7c9935a5afffbcc03f8e5d.png',
preview: preview:
'WWF works to sustain the natural world for the benefit of people and wildlife, collaborating with partners from local to global levels in nearly 100 countries.', 'WWF works to sustain the natural world for the benefit of people and wildlife, collaborating with partners from local to global levels in nearly 100 countries.',
description: description:
@ -274,7 +258,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
{ {
name: 'UNICEF USA', name: 'UNICEF USA',
website: 'https://www.unicefusa.org/', website: 'https://www.unicefusa.org/',
photo: 'https://www.unicefusa.org/sites/default/files/UNICEFUSA_DIG_C.svg', photo: 'https://i.imgur.com/9cxuvZi.png',
ein: '13-1760110', ein: '13-1760110',
preview: preview:
"UNICEF USA helps save and protect the world's most vulnerable children.", "UNICEF USA helps save and protect the world's most vulnerable children.",
@ -285,8 +269,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Vitamin Angels', name: 'Vitamin Angels',
website: 'https://www.vitaminangels.org/', website: 'https://www.vitaminangels.org/',
ein: '77-0485881', ein: '77-0485881',
photo: photo: 'https://i.imgur.com/Mf35IOu.jpg',
'https://www.newhope.com/sites/newhope360.com/files/styles/article_featured_retina/public/vitamin-angels-logo.jpg?itok=pfNCPLE0',
preview: preview:
'By improving access to vital nutrition, everyone gets an equal chance to grow, thrive, and prosper.', 'By improving access to vital nutrition, everyone gets an equal chance to grow, thrive, and prosper.',
description: description:
@ -296,7 +279,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Free Software Foundation', name: 'Free Software Foundation',
website: 'https://www.fsf.org/', website: 'https://www.fsf.org/',
ein: '04-2888848', ein: '04-2888848',
photo: 'https://www.gnu.org/graphics/logo-fsf.org.png', photo: 'https://i.imgur.com/z87sFDE.png',
preview: preview:
'The Free Software Foundation (FSF) is a nonprofit with a worldwide mission to promote computer user freedom.', 'The Free Software Foundation (FSF) is a nonprofit with a worldwide mission to promote computer user freedom.',
description: description:
@ -306,8 +289,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Direct Relief', name: 'Direct Relief',
website: 'https://www.directrelief.org/', website: 'https://www.directrelief.org/',
ein: '95-1831116', ein: '95-1831116',
photo: photo: 'https://i.imgur.com/QS7kHAU.png',
'https://www.ngoadvisor.net/wp-content/uploads/2016/02/DirectRelief_Logo_RGB-2-1920x576.png',
preview: preview:
'Direct Relief is a humanitarian aid organization, active in all 50 states and more than 80 countries, with a mission to improve the health and lives of people affected by poverty or emergencies without regard to politics, religion, or ability to pay.', 'Direct Relief is a humanitarian aid organization, active in all 50 states and more than 80 countries, with a mission to improve the health and lives of people affected by poverty or emergencies without regard to politics, religion, or ability to pay.',
description: description:
@ -317,8 +299,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'World Resources Institute', name: 'World Resources Institute',
website: 'https://www.wri.org/', website: 'https://www.wri.org/',
ein: '52-1257057', ein: '52-1257057',
photo: photo: 'https://i.imgur.com/Bi6MgYI.png',
'https://www.americansecurityproject.org/wp-content/uploads/2016/11/WRI_logo_4c.png',
preview: preview:
'WRI is a global nonprofit organization that works with leaders in government, business and civil society to research, design, and carry out practical solutions that simultaneously improve peoples lives and ensure nature can thrive.', 'WRI is a global nonprofit organization that works with leaders in government, business and civil society to research, design, and carry out practical solutions that simultaneously improve peoples lives and ensure nature can thrive.',
description: description:
@ -328,8 +309,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'ProPublica', name: 'ProPublica',
website: 'https://www.propublica.org/', website: 'https://www.propublica.org/',
ein: '14-2007220', ein: '14-2007220',
photo: photo: 'https://i.imgur.com/R5Vt3Pb.png',
'https://seekvectorlogo.com/wp-content/uploads/2018/09/propublica-vector-logo.png',
preview: preview:
'The mission: to expose abuses of power and betrayals of the public trust by government, business, and other institutions, using the moral force of investigative journalism to spur reform through the sustained spotlighting of wrongdoing.', 'The mission: to expose abuses of power and betrayals of the public trust by government, business, and other institutions, using the moral force of investigative journalism to spur reform through the sustained spotlighting of wrongdoing.',
description: description:
@ -339,8 +319,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Dana-Farber Cancer Institute', name: 'Dana-Farber Cancer Institute',
website: 'https://www.dana-farber.org/', website: 'https://www.dana-farber.org/',
ein: '04-2263040', ein: '04-2263040',
photo: photo: 'https://i.imgur.com/SQNn97p.png',
'https://www.danafarbermasterclass.com/assets/images/DFCI-logo-lens-stacked.png',
preview: preview:
"For over 70 years, we've led the world by making life-changing breakthroughs in cancer research and patient care, providing the most advanced treatments available.", "For over 70 years, we've led the world by making life-changing breakthroughs in cancer research and patient care, providing the most advanced treatments available.",
description: description:
@ -350,8 +329,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'Save The Children', name: 'Save The Children',
website: 'https://www.savethechildren.org/', website: 'https://www.savethechildren.org/',
ein: '06-0726487', ein: '06-0726487',
photo: photo: 'https://i.imgur.com/GngYPBI.png',
'https://www.thisisclapham.co.uk/wp-content/uploads/2016/08/savethechildren.png',
preview: preview:
'Through the decades, Save the Children has continued to work to save childrens lives, and thats still what we do today.', 'Through the decades, Save the Children has continued to work to save childrens lives, and thats still what we do today.',
description: description:
@ -361,8 +339,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'World Central Kitchen Incorporated', name: 'World Central Kitchen Incorporated',
website: 'https://wck.org/', website: 'https://wck.org/',
ein: '27-3521132', ein: '27-3521132',
photo: photo: 'https://i.imgur.com/te93MaY.png',
'https://res.cloudinary.com/dktp1ybbx/image/upload/f_auto,fl_lossy,q_auto/v1560203222/organization/prod/924457/M0oxO9vaxO.png',
preview: preview:
'WCK is first to the frontlines, providing meals in response to humanitarian, climate, and community crises. We build resilient food systems with locally led solutions.', 'WCK is first to the frontlines, providing meals in response to humanitarian, climate, and community crises. We build resilient food systems with locally led solutions.',
description: description:
@ -372,8 +349,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
name: 'The Johns Hopkins Center for Health Security', name: 'The Johns Hopkins Center for Health Security',
website: 'https://www.centerforhealthsecurity.org/', website: 'https://www.centerforhealthsecurity.org/',
ein: '', ein: '',
photo: photo: 'https://i.imgur.com/gKZE2Xs.png',
'https://www.centerforhealthsecurity.org/sebin/d/d/CHS.logo.horizontal.blue.png',
preview: preview:
'Our mission: to protect peoples health from epidemics and disasters and ensure that communities are resilient to major challenges.', 'Our mission: to protect peoples health from epidemics and disasters and ensure that communities are resilient to major challenges.',
description: description:
@ -382,8 +358,7 @@ Future plans: We expect to focus on similar theoretical problems in alignment un
{ {
name: 'ALLFED', name: 'ALLFED',
website: 'https://allfed.info/', website: 'https://allfed.info/',
photo: photo: 'https://i.imgur.com/p235vwF.jpg',
'https://images1.the-dots.com/1860424/allfed-logo-1.png?p=projectImageFullJpg',
ein: '27-6601178', ein: '27-6601178',
preview: 'Feeding everyone no matter what.', preview: 'Feeding everyone no matter what.',
description: description:

View File

@ -56,7 +56,9 @@ export function AddLiquidityPanel(props: { contract: Contract }) {
return ( return (
<> <>
<div>Subsidize this market by adding liquidity for traders.</div> <div className="text-gray-500">
Subsidize this market by adding liquidity for traders.
</div>
<Row> <Row>
<AmountInput <AmountInput

View File

@ -45,7 +45,7 @@ export function AmountInput(props: {
<span className="bg-gray-200 text-sm">{label}</span> <span className="bg-gray-200 text-sm">{label}</span>
<input <input
className={clsx( className={clsx(
'input input-bordered', 'input input-bordered max-w-[200px] text-lg',
error && 'input-error', error && 'input-error',
inputClassName inputClassName
)} )}

View File

@ -116,7 +116,7 @@ export function AnswerBetPanel(props: {
</Row> </Row>
<div className="my-3 text-left text-sm text-gray-500">Amount </div> <div className="my-3 text-left text-sm text-gray-500">Amount </div>
<BuyAmountInput <BuyAmountInput
inputClassName="w-full" inputClassName="w-full max-w-none"
amount={betAmount} amount={betAmount}
onChange={setBetAmount} onChange={setBetAmount}
error={error} error={error}

View File

@ -62,7 +62,7 @@ export function BetPanel(props: {
className className
)} )}
> >
<div className="mb-6 text-2xl text-gray-700">Place a trade</div> <div className="mb-6 text-2xl">Place your bet</div>
{/* <Title className={clsx('!mt-0 text-neutral')} text="Place a trade" /> */} {/* <Title className={clsx('!mt-0 text-neutral')} text="Place a trade" /> */}
<BuyPanel contract={contract} user={user} userBets={userBets ?? []} /> <BuyPanel contract={contract} user={user} userBets={userBets ?? []} />
@ -125,6 +125,7 @@ export function BetPanelSwitcher(props: {
<BinaryOutcomeLabel outcome={sharesOutcome} /> shares <BinaryOutcomeLabel outcome={sharesOutcome} /> shares
</div> </div>
{tradeType === 'BUY' && (
<button <button
className="btn btn-sm" className="btn btn-sm"
style={{ style={{
@ -133,11 +134,14 @@ export function BetPanelSwitcher(props: {
color: '#3D4451', color: '#3D4451',
}} }}
onClick={() => onClick={() =>
tradeType === 'BUY' ? setTradeType('SELL') : setTradeType('BUY') tradeType === 'BUY'
? setTradeType('SELL')
: setTradeType('BUY')
} }
> >
{tradeType === 'BUY' ? 'Sell' : 'Bet'} {tradeType === 'BUY' ? 'Sell' : 'Bet'}
</button> </button>
)}
</Row> </Row>
</Col> </Col>
)} )}
@ -299,7 +303,7 @@ function BuyPanel(props: {
/> />
<div className="my-3 text-left text-sm text-gray-500">Amount</div> <div className="my-3 text-left text-sm text-gray-500">Amount</div>
<BuyAmountInput <BuyAmountInput
inputClassName="w-full" inputClassName="w-full max-w-none"
amount={betAmount} amount={betAmount}
onChange={onBetChange} onChange={onBetChange}
error={error} error={error}

View File

@ -1,8 +1,10 @@
import { StarIcon } from '@heroicons/react/solid' import { StarIcon } from '@heroicons/react/solid'
import _ from 'lodash' import _ from 'lodash'
import Link from 'next/link' import Link from 'next/link'
import Image from 'next/image'
import { Charity } from '../../../common/charity' import { Charity } from '../../../common/charity'
import { useCharityTxns } from '../../hooks/use-charity-txns' import { useCharityTxns } from '../../hooks/use-charity-txns'
import { manaToUSD } from '../../pages/charity/[charitySlug]'
import { Row } from '../layout/row' import { Row } from '../layout/row'
export function CharityCard(props: { charity: Charity }) { export function CharityCard(props: { charity: Charity }) {
@ -18,9 +20,9 @@ export function CharityCard(props: { charity: Charity }) {
{tags?.includes('Featured') && <FeaturedBadge />} {tags?.includes('Featured') && <FeaturedBadge />}
</Row> </Row>
<figure className="h-32 px-4 pt-4"> <figure className="relative h-32 p-4">
{photo ? ( {photo ? (
<img className="h-full w-full object-contain" src={photo} alt="" /> <Image src={photo} alt="" layout="fill" objectFit="contain" />
) : ( ) : (
<div className="h-full w-full bg-gradient-to-r from-slate-300 to-indigo-200" /> <div className="h-full w-full bg-gradient-to-r from-slate-300 to-indigo-200" />
)} )}
@ -31,7 +33,9 @@ export function CharityCard(props: { charity: Charity }) {
{raised > 0 && ( {raised > 0 && (
<Row className="text-primary mt-4 flex-1 items-end justify-center gap-2"> <Row className="text-primary mt-4 flex-1 items-end justify-center gap-2">
<span className="text-3xl"> <span className="text-3xl">
${Math.floor((raised ?? 0) / 100)} {raised < 100
? manaToUSD(raised)
: '$' + Math.floor(raised / 100)}
</span> </span>
<span>raised</span> <span>raised</span>
</Row> </Row>

View File

@ -0,0 +1,34 @@
import { Txn } from '../../../common/txn'
import { Avatar } from '../avatar'
import { useUserById } from '../../hooks/use-users'
import { UserLink } from '../user-page'
import { manaToUSD } from '../../pages/charity/[charitySlug]'
import { RelativeTimestamp } from '../feed/feed-items'
export function Donation(props: { txn: Txn }) {
const { txn } = props
const user = useUserById(txn.fromId)
if (!user) {
return <>Loading...</>
}
return (
<div className="mb-2 flow-root pr-2 md:pr-0">
<div className="relative flex items-center space-x-3">
<Avatar username={user.name} avatarUrl={user.avatarUrl} size="sm" />
<div className="min-w-0 flex-1">
<p className="mt-0.5 text-sm text-gray-500">
<UserLink
className="text-gray-500"
username={user.username}
name={user.name}
/>{' '}
donated {manaToUSD(txn.amount)}
<RelativeTimestamp time={txn.createdTime} />
</p>
</div>
</div>
</div>
)
}

View File

@ -49,7 +49,19 @@ export function ContractInfoDialog(props: { contract: Contract; bets: Bet[] }) {
<Col className="gap-4 rounded bg-white p-6"> <Col className="gap-4 rounded bg-white p-6">
<Title className="!mt-0 !mb-0" text="Market info" /> <Title className="!mt-0 !mb-0" text="Market info" />
<div className="text-gray-500">Stats</div> <div>Share</div>
<Row className="justify-start gap-4">
<CopyLinkButton contract={contract} />
<TweetButton
className="self-start"
tweetText={getTweetText(contract, false)}
/>
<ShareEmbedButton contract={contract} />
</Row>
<div />
<div>Stats</div>
<table className="table-compact table-zebra table w-full text-gray-500"> <table className="table-compact table-zebra table w-full text-gray-500">
<tbody> <tbody>
<tr> <tr>
@ -97,19 +109,7 @@ export function ContractInfoDialog(props: { contract: Contract; bets: Bet[] }) {
</tbody> </tbody>
</table> </table>
<div className="text-gray-500">Share</div> <div>Tags</div>
<Row className="justify-start gap-4">
<CopyLinkButton contract={contract} />
<TweetButton
className="self-start"
tweetText={getTweetText(contract, false)}
/>
<ShareEmbedButton contract={contract} />
</Row>
<div />
<div className="text-gray-500">Tags</div>
<TagsInput contract={contract} /> <TagsInput contract={contract} />
<div /> <div />
@ -117,7 +117,7 @@ export function ContractInfoDialog(props: { contract: Contract; bets: Bet[] }) {
!contract.resolution && !contract.resolution &&
(!closeTime || closeTime > Date.now()) && ( (!closeTime || closeTime > Date.now()) && (
<> <>
<div className="text-gray-500">Add liquidity</div> <div className="">Add liquidity</div>
<AddLiquidityPanel contract={contract} /> <AddLiquidityPanel contract={contract} />
</> </>
)} )}

View File

@ -17,6 +17,7 @@ import { AnswersGraph } from '../answers/answers-graph'
import { DPM, FreeResponse, FullContract } from '../../../common/contract' import { DPM, FreeResponse, FullContract } from '../../../common/contract'
import { ContractDescription } from './contract-description' import { ContractDescription } from './contract-description'
import { ContractDetails } from './contract-details' import { ContractDetails } from './contract-details'
import { ShareMarket } from '../share-market'
export const ContractOverview = (props: { export const ContractOverview = (props: {
contract: Contract contract: Contract
@ -84,7 +85,9 @@ export const ContractOverview = (props: {
/> />
)} )}
{contract.description && <Spacer h={6} />} {(contract.description || isCreator) && <Spacer h={6} />}
{isCreator && <ShareMarket className="px-2" contract={contract} />}
<ContractDescription <ContractDescription
className="px-2" className="px-2"

View File

@ -1,6 +1,7 @@
import { Fragment } from 'react' import { Fragment } from 'react'
import { LinkIcon } from '@heroicons/react/outline' import { LinkIcon } from '@heroicons/react/outline'
import { Menu, Transition } from '@headlessui/react' import { Menu, Transition } from '@headlessui/react'
import clsx from 'clsx'
import { Contract } from '../../common/contract' import { Contract } from '../../common/contract'
import { copyToClipboard } from '../lib/util/copy' import { copyToClipboard } from '../lib/util/copy'
import { contractPath } from '../lib/firebase/contracts' import { contractPath } from '../lib/firebase/contracts'
@ -10,8 +11,11 @@ function copyContractUrl(contract: Contract) {
copyToClipboard(`https://${ENV_CONFIG.domain}${contractPath(contract)}`) copyToClipboard(`https://${ENV_CONFIG.domain}${contractPath(contract)}`)
} }
export function CopyLinkButton(props: { contract: Contract }) { export function CopyLinkButton(props: {
const { contract } = props contract: Contract
buttonClassName?: string
}) {
const { contract, buttonClassName } = props
return ( return (
<Menu <Menu
@ -20,12 +24,10 @@ export function CopyLinkButton(props: { contract: Contract }) {
onMouseUp={() => copyContractUrl(contract)} onMouseUp={() => copyContractUrl(contract)}
> >
<Menu.Button <Menu.Button
className="btn btn-xs normal-case" className={clsx(
style={{ 'btn btn-xs border-2 border-green-600 bg-white normal-case text-green-600 hover:border-green-600 hover:bg-white',
backgroundColor: 'white', buttonClassName
border: '2px solid #16A34A', )}
color: '#16A34A', // text-green-600
}}
> >
<LinkIcon className="mr-1.5 h-4 w-4" aria-hidden="true" /> <LinkIcon className="mr-1.5 h-4 w-4" aria-hidden="true" />
Copy link Copy link

View File

@ -333,7 +333,7 @@ export function CommentInput(props: {
) )
} }
function RelativeTimestamp(props: { time: number }) { export function RelativeTimestamp(props: { time: number }) {
const { time } = props const { time } = props
return ( return (
<DateTimeTooltip time={time}> <DateTimeTooltip time={time}>

View File

@ -72,9 +72,9 @@ export function ResolutionPanel(props: {
return ( return (
<Col className={clsx('rounded-md bg-white px-8 py-6', className)}> <Col className={clsx('rounded-md bg-white px-8 py-6', className)}>
<Title className="!mt-0 whitespace-nowrap" text="Resolve market" /> <div className="mb-6 whitespace-nowrap text-2xl">Resolve market</div>
<div className="mb-2 text-sm text-gray-500">Outcome</div> <div className="mb-3 text-sm text-gray-500">Outcome</div>
<YesNoCancelSelector <YesNoCancelSelector
className="mx-auto my-2" className="mx-auto my-2"

View File

@ -0,0 +1,26 @@
import clsx from 'clsx'
import { Contract, contractUrl } from '../lib/firebase/contracts'
import { CopyLinkButton } from './copy-link-button'
import { Col } from './layout/col'
import { Row } from './layout/row'
export function ShareMarket(props: { contract: Contract; className?: string }) {
const { contract, className } = props
return (
<Col className={clsx(className, 'gap-3')}>
<div>Share your market</div>
<Row className="mb-6 items-center">
<input
className="input input-bordered flex-1 rounded-r-none text-gray-500"
type="text"
value={contractUrl(contract)}
/>
<CopyLinkButton
contract={contract}
buttonClassName="btn-md rounded-l-none"
/>
</Row>
</Col>
)
}

View File

@ -26,10 +26,8 @@ export const useSaveShares = (
_.sumBy(noBets, (bet) => bet.shares), _.sumBy(noBets, (bet) => bet.shares),
] ]
const [yesFloorShares, noFloorShares] = [ const yesFloorShares = Math.round(yesShares) === 0 ? 0 : Math.floor(yesShares)
Math.floor(yesShares), const noFloorShares = Math.round(noShares) === 0 ? 0 : Math.floor(noShares)
Math.floor(noShares),
]
useEffect(() => { useEffect(() => {
// Save yes and no shares to local storage. // Save yes and no shares to local storage.

View File

@ -1,6 +1,9 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Txn } from '../../common/txn' import { Txn } from '../../common/txn'
import { listenForCharityTxns } from '../lib/firebase/txns' import {
listenForAllCharityTxns,
listenForCharityTxns,
} from '../lib/firebase/txns'
export const useCharityTxns = (charityId: string) => { export const useCharityTxns = (charityId: string) => {
const [txns, setTxns] = useState<Txn[]>([]) const [txns, setTxns] = useState<Txn[]>([])
@ -11,3 +14,13 @@ export const useCharityTxns = (charityId: string) => {
return txns return txns
} }
export const useAllCharityTxns = () => {
const [txns, setTxns] = useState<Txn[]>([])
useEffect(() => {
return listenForAllCharityTxns(setTxns)
}, [])
return txns
}

View File

@ -26,6 +26,7 @@ import { DAY_MS } from '../../../common/util/time'
import { MAX_FEED_CONTRACTS } from '../../../common/recommended-contracts' import { MAX_FEED_CONTRACTS } from '../../../common/recommended-contracts'
import { Bet } from '../../../common/bet' import { Bet } from '../../../common/bet'
import { Comment } from '../../../common/comment' import { Comment } from '../../../common/comment'
import { ENV_CONFIG } from '../../../common/envs/constants'
export type { Contract } export type { Contract }
export function contractPath(contract: Contract) { export function contractPath(contract: Contract) {
@ -36,6 +37,10 @@ export function homeContractPath(contract: Contract) {
return `/home?c=${contract.slug}` return `/home?c=${contract.slug}`
} }
export function contractUrl(contract: Contract) {
return `https://${ENV_CONFIG.domain}${contractPath(contract)}`
}
export function contractMetrics(contract: Contract) { export function contractMetrics(contract: Contract) {
const { createdTime, resolutionTime, isResolved } = contract const { createdTime, resolutionTime, isResolved } = contract

View File

@ -21,3 +21,9 @@ export function listenForCharityTxns(
) { ) {
return listenForValues<Txn>(getCharityQuery(charityId), setTxns) return listenForValues<Txn>(getCharityQuery(charityId), setTxns)
} }
const charitiesQuery = query(txnCollection, where('toType', '==', 'CHARITY'))
export function listenForAllCharityTxns(setTxns: (txns: Txn[]) => void) {
return listenForValues<Txn>(charitiesQuery, setTxns)
}

View File

@ -8,7 +8,7 @@ module.exports = {
optimizeCss: true, optimizeCss: true,
}, },
images: { images: {
domains: ['lh3.googleusercontent.com'], domains: ['lh3.googleusercontent.com', 'i.imgur.com'],
}, },
async redirects() { async redirects() {
return [ return [

View File

@ -18,7 +18,7 @@ import { getDailyNewUsers } from '../lib/firebase/users'
export const getStaticProps = fromPropz(getStaticPropz) export const getStaticProps = fromPropz(getStaticPropz)
export async function getStaticPropz() { export async function getStaticPropz() {
const numberOfDays = 80 const numberOfDays = 90
const today = dayjs(dayjs().format('YYYY-MM-DD')) const today = dayjs(dayjs().format('YYYY-MM-DD'))
const startDate = today.subtract(numberOfDays, 'day') const startDate = today.subtract(numberOfDays, 'day')
@ -367,7 +367,7 @@ export function CustomAnalytics(props: {
<Title text="Ratio of Active Users" /> <Title text="Ratio of Active Users" />
<Tabs <Tabs
defaultIndex={0} defaultIndex={1}
tabs={[ tabs={[
{ {
title: 'Daily / Weekly', title: 'Daily / Weekly',

View File

@ -17,8 +17,10 @@ import Custom404 from '../404'
import { useCharityTxns } from '../../hooks/use-charity-txns' import { useCharityTxns } from '../../hooks/use-charity-txns'
import { useWindowSize } from '../../hooks/use-window-size' import { useWindowSize } from '../../hooks/use-window-size'
import Confetti from 'react-confetti' import Confetti from 'react-confetti'
import { Donation } from '../../components/charity/feed-items'
import Image from 'next/image'
const manaToUSD = (mana: number) => export const manaToUSD = (mana: number) =>
(mana / 100).toLocaleString('en-US', { style: 'currency', currency: 'USD' }) (mana / 100).toLocaleString('en-US', { style: 'currency', currency: 'USD' })
export default function CharityPageWrapper() { export default function CharityPageWrapper() {
@ -41,6 +43,7 @@ function CharityPage(props: { charity: Charity }) {
const user = useUser() const user = useUser()
const txns = useCharityTxns(charity.id) const txns = useCharityTxns(charity.id)
const newToOld = _.sortBy(txns, (txn) => -txn.createdTime)
const totalRaised = _.sumBy(txns, (txn) => txn.amount) const totalRaised = _.sumBy(txns, (txn) => txn.amount)
const fromYou = _.sumBy( const fromYou = _.sumBy(
txns.filter((txn) => txn.fromId === user?.id), txns.filter((txn) => txn.fromId === user?.id),
@ -76,11 +79,9 @@ function CharityPage(props: { charity: Charity }) {
{/* TODO: donations over time chart */} {/* TODO: donations over time chart */}
<Row className="justify-between"> <Row className="justify-between">
{photo && ( {photo && (
<img <div className="relative w-40 rounded-2xl">
src={photo} <Image src={photo} alt="" layout="fill" objectFit="contain" />
alt="" </div>
className="w-40 rounded-2xl object-contain"
/>
)} )}
<Details <Details
charity={charity} charity={charity}
@ -91,6 +92,9 @@ function CharityPage(props: { charity: Charity }) {
</Row> </Row>
<h2 className="mt-7 mb-2 text-xl text-indigo-700">About</h2> <h2 className="mt-7 mb-2 text-xl text-indigo-700">About</h2>
<Blurb text={description} /> <Blurb text={description} />
{newToOld.map((txn) => (
<Donation key={txn.id} txn={txn} />
))}
</Col> </Col>
</Col> </Col>
</Page> </Page>
@ -98,8 +102,7 @@ function CharityPage(props: { charity: Charity }) {
} }
function Blurb({ text }: { text: string }) { function Blurb({ text }: { text: string }) {
// Default to open for now (aka don't actually hide any text yet.) const [open, setOpen] = useState(false)
const [open, setOpen] = useState(true)
// Calculate whether the full blurb is already shown // Calculate whether the full blurb is already shown
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLDivElement>(null)
@ -125,7 +128,7 @@ function Blurb({ text }: { text: string }) {
onClick={() => setOpen(!open)} onClick={() => setOpen(!open)}
className={clsx( className={clsx(
'btn btn-link capitalize-none my-3 normal-case text-indigo-700', 'btn btn-link capitalize-none my-3 normal-case text-indigo-700',
hideExpander && 'hidden' hideExpander && 'invisible'
)} )}
> >
{open ? 'Hide' : 'Read more'} {open ? 'Hide' : 'Read more'}
@ -204,7 +207,7 @@ function DonationBox(props: {
Amount Amount
</label> </label>
<BuyAmountInput <BuyAmountInput
inputClassName="w-full donate-input" inputClassName="w-full max-w-none donate-input"
amount={amount} amount={amount}
onChange={setAmount} onChange={setAmount}
error={error} error={error}

View File

@ -1,26 +1,37 @@
import _ from 'lodash' import _ from 'lodash'
import { useState, useMemo } from 'react' import { useState, useMemo } from 'react'
import { charities as charityList } from '../../../common/charity' import { charities } from '../../../common/charity'
import { CharityCard } from '../../components/charity/charity-card' import { CharityCard } from '../../components/charity/charity-card'
import { Col } from '../../components/layout/col' import { Col } from '../../components/layout/col'
import { Spacer } from '../../components/layout/spacer'
import { Page } from '../../components/page' import { Page } from '../../components/page'
import { SiteLink } from '../../components/site-link'
import { Title } from '../../components/title' import { Title } from '../../components/title'
import { useAllCharityTxns } from '../../hooks/use-charity-txns'
const charities = charityList.map((charity) => ({
...charity,
raised: 4001,
}))
export default function Charity() { export default function Charity() {
const allCharityTxn = useAllCharityTxns()
const totals = _.mapValues(_.groupBy(allCharityTxn, 'toId'), (txns) =>
_.sumBy(txns, (txn) => txn.amount)
)
const totalRaised = _.sum(Object.values(totals))
// TODO: show loading state while totals are calculating
const sortedCharities = _.sortBy(charities, [
(charity) => (charity.tags?.includes('Featured') ? 0 : 1),
(charity) => -totals[charity.id],
])
const [query, setQuery] = useState('') const [query, setQuery] = useState('')
const debouncedQuery = _.debounce(setQuery, 50) const debouncedQuery = _.debounce(setQuery, 50)
const filterCharities = useMemo( const filterCharities = useMemo(
() => () =>
charities.filter((charity) => sortedCharities.filter((charity) =>
charity.name.toLowerCase().includes(query.toLowerCase()) charity.name.toLowerCase().includes(query.toLowerCase())
), ),
[query] [query, sortedCharities]
) )
return ( return (
@ -31,6 +42,9 @@ export default function Charity() {
<div className="mb-6 text-gray-500"> <div className="mb-6 text-gray-500">
Donate your winnings to charity! Through the month of May, every M$ Donate your winnings to charity! Through the month of May, every M$
100 you contribute turns into $1 USD sent to your chosen charity. 100 you contribute turns into $1 USD sent to your chosen charity.
<Spacer h={5} />
Together we've donated over ${Math.floor(totalRaised / 100)} USD so
far!
</div> </div>
<input <input
@ -60,8 +74,14 @@ export default function Charity() {
></iframe> ></iframe>
<div className="mt-10 text-gray-500"> <div className="mt-10 text-gray-500">
Don't see your favorite charity? Recommend that we add it by emailing Don't see your favorite charity? Recommend it{' '}
<span className="text-indigo-500"> give@manifold.markets</span>~ <SiteLink
href="https://manifold.markets/Sinclair/which-charities-should-manifold-add"
className="text-indigo-700"
>
here
</SiteLink>
!
<br /> <br />
<br /> <br />
<span className="italic"> <span className="italic">