All files / owid-grapher/site/blocks CookiePreferences.tsx

37.18% Statements 29/78
100% Branches 0/0
0% Functions 0/2
37.18% Lines 29/78

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 1401x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x                                                                               1x 1x                                                                                                                                                
import moment from "moment"
import * as React from "react"
import * as ReactDOM from "react-dom"
import {
    Action,
    DATE_FORMAT,
    getPreferenceValue,
    getTodayDate,
    Preference,
    PreferenceType,
} from "../../site/CookiePreferencesManager"
import slugify from "slugify"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faCheck } from "@fortawesome/free-solid-svg-icons/faCheck"
import { SiteAnalytics } from "../../site/SiteAnalytics"
 
const ANALYTICS_ACTION = "cookie-preferences"
const analytics = new SiteAnalytics()
 
// Note: CookiePreferences has been designed to be rendered through a portal
// only. When this becomes limiting (e.g. cookies preferences rendered both in
// the content and in the cookie bar), then at least two things need to be taken
// care of:
// - unique IDs for input elements in CookiePreference
// - support for in-place rendering
 
const CookiePreference = ({
    title,
    name,
    consent,
    disabled,
    toggleConsent,
    children,
}: {
    title: string
    name: string
    consent: boolean
    disabled?: boolean
    toggleConsent?: any
    children: React.ReactNode
}) => {
    const id = `cookie-preference-${slugify(name, { lower: true })}`

    const onChange = () => {
        toggleConsent()
        analytics.logSiteClick(
            ANALYTICS_ACTION,
            `${consent ? "Refuse" : "Accept"} ${name}`
        )
    }

    return (
        <div className="cookie-preference">
            <input
                id={id}
                type="checkbox"
                onChange={onChange}
                checked={consent}
                disabled={disabled}
                data-test={`${name}-preference`}
            ></input>
            <label htmlFor={id}>{title}</label>
            <div className="description">{children}</div>
        </div>
    )
}
 
export const CookiePreferences = ({
    preferences,
    date,
    dispatch,
}: {
    preferences: Preference[]
    date?: number
    dispatch: any
}) => {
    const cookiePreferencesDomSlot = document.querySelector(
        ".wp-block-cookie-preferences"
    )
    if (!cookiePreferencesDomSlot) return null
 
    return ReactDOM.createPortal(
        <div data-test="cookie-preferences" className="cookie-preferences">
            <CookiePreference
                title="Necessary cookies"
                name="necessary"
                consent={true}
                disabled={true}
            >
                The website cannot function properly without these cookies. If
                you wish, you can disable cookies completely in your browser
                preferences.
            </CookiePreference>
            <CookiePreference
                title="Analytics cookies"
                name="analytics"
                consent={getPreferenceValue(
                    PreferenceType.Analytics,
                    preferences
                )}
                toggleConsent={() =>
                    dispatch({
                        type: Action.TogglePreference,
                        payload: {
                            preferenceType: PreferenceType.Analytics,
                            date: getTodayDate(),
                        },
                    })
                }
            >
                We use these cookies to monitor and improve website performance.
            </CookiePreference>
            {date ? (
                <div className="last-updated">
                    Preferences last updated:{" "}
                    {moment(date, DATE_FORMAT).format("LL")}
                </div>
            ) : (
                <button
                    className="owid-button"
                    onClick={() =>
                        dispatch({
                            type: Action.Accept,
                            payload: { date: getTodayDate() },
                        })
                    }
                    data-test="accept"
                    data-track-note={ANALYTICS_ACTION}
                >
                    <span className="icon">
                        <FontAwesomeIcon icon={faCheck} />
                    </span>
                    I agree
                </button>
            )}
        </div>,
        cookiePreferencesDomSlot
    )
}