Improve dark mode (#5819)
* Improve dark mode - Switch from `slate` to `zinc` for the gray color palette - Darken overall dark mode UI - Switch from `green` to `emerald` for the green color palette - Update a few previously missed instances of title case to sentence case - Consolidate button styles and change naming from `bright` to `secondary` - Update button disabled styles - Fix tooltip not adjusting to content width - Update graph tooltip layout and typography - Add transition effects to hover states - Reduce footer logo size * Fix oversights - Update funnel graph colors - Update graph grid colors - Improve focus styles - Improve disabled input styles * Fix more oversights in relation to dashboard filtering - Improve consistency of input, button, combobox and modal components in relation to settings area - Fix segment tooltip color * Fix search input style in funnel and segments dropdowns * Add white background to favicon images in dark mode - The GitHub and ChatGPT favicons are hard to see in dark mode, so we add a white background to them. * Fix tooltip color to fit all backgrounds in dark mode * Fix tests * Fixed more tests * Extract SourceFavicon component to eliminate favicon duplication * Fix regression on installation page after rebase * Fix formatting issues * Fix favicon test failure in CI by reading placeholder icon at compile time * Undo previous commit
This commit is contained in:
parent
46f05d81c9
commit
91363a2825
|
|
@ -4,7 +4,6 @@
|
|||
@import './loader.css' layer(components);
|
||||
@import './tooltip.css' layer(components);
|
||||
@import './flatpickr-colors.css' layer(components);
|
||||
@import './chartjs.css' layer(components);
|
||||
|
||||
@plugin "@tailwindcss/forms";
|
||||
|
||||
|
|
@ -28,6 +27,24 @@
|
|||
[role='button']:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
*:focus-visible {
|
||||
@apply ring-2 ring-indigo-500 ring-offset-2 dark:ring-offset-gray-900 outline-none;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
/* Replace Tailwind form plugin's focus with focus-visible */
|
||||
[type='checkbox']:focus,
|
||||
[type='radio']:focus {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
[type='checkbox']:focus-visible,
|
||||
[type='radio']:focus-visible {
|
||||
@apply ring-2 ring-indigo-500 ring-offset-2 outline-none;
|
||||
}
|
||||
}
|
||||
|
||||
@theme {
|
||||
|
|
@ -45,28 +62,40 @@
|
|||
--color-yellow-800: var(--color-amber-800);
|
||||
--color-yellow-900: var(--color-amber-900);
|
||||
--color-yellow-950: var(--color-amber-950);
|
||||
--color-green-50: var(--color-emerald-50);
|
||||
--color-green-100: var(--color-emerald-100);
|
||||
--color-green-200: var(--color-emerald-200);
|
||||
--color-green-300: var(--color-emerald-300);
|
||||
--color-green-400: var(--color-emerald-400);
|
||||
--color-green-500: var(--color-emerald-500);
|
||||
--color-green-600: var(--color-emerald-600);
|
||||
--color-green-700: var(--color-emerald-700);
|
||||
--color-green-800: var(--color-emerald-800);
|
||||
--color-green-900: var(--color-emerald-900);
|
||||
--color-green-950: var(--color-emerald-950);
|
||||
|
||||
/* gray: colors.slate - Map gray to slate colors */
|
||||
--color-gray-50: var(--color-slate-50);
|
||||
--color-gray-100: var(--color-slate-100);
|
||||
--color-gray-200: var(--color-slate-200);
|
||||
--color-gray-300: var(--color-slate-300);
|
||||
--color-gray-400: var(--color-slate-400);
|
||||
--color-gray-500: var(--color-slate-500);
|
||||
--color-gray-600: var(--color-slate-600);
|
||||
--color-gray-700: var(--color-slate-700);
|
||||
--color-gray-800: var(--color-slate-800);
|
||||
--color-gray-900: var(--color-slate-900);
|
||||
--color-gray-50: var(--color-zinc-50);
|
||||
--color-gray-100: var(--color-zinc-100);
|
||||
--color-gray-200: var(--color-zinc-200);
|
||||
--color-gray-300: var(--color-zinc-300);
|
||||
--color-gray-400: var(--color-zinc-400);
|
||||
--color-gray-500: var(--color-zinc-500);
|
||||
--color-gray-600: var(--color-zinc-600);
|
||||
--color-gray-700: var(--color-zinc-700);
|
||||
--color-gray-800: var(--color-zinc-800);
|
||||
--color-gray-900: var(--color-zinc-900);
|
||||
--color-gray-950: var(--color-zinc-950);
|
||||
|
||||
/* Custom gray shades from config (override some slate values) */
|
||||
--color-gray-150: rgb(234 238 244);
|
||||
--color-gray-825: rgb(37 47 63);
|
||||
--color-gray-850: rgb(26 32 44);
|
||||
--color-gray-950: rgb(13 18 30);
|
||||
--color-gray-150: rgb(236 236 238);
|
||||
--color-gray-750: rgb(50 50 54);
|
||||
--color-gray-825: rgb(35 35 38);
|
||||
--color-gray-850: rgb(34 34 38);
|
||||
|
||||
/* Set v3 default ring behavior */
|
||||
--default-ring-width: 3px;
|
||||
--default-ring-color: var(--color-blue-500);
|
||||
--default-ring-width: 2px;
|
||||
--default-ring-color: var(--color-indigo-500);
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
|
@ -91,7 +120,7 @@
|
|||
}
|
||||
|
||||
.button {
|
||||
@apply inline-flex justify-center px-3.5 py-2 text-sm font-medium text-white bg-indigo-600 border border-transparent rounded-md leading-5 transition hover:bg-indigo-700 focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500;
|
||||
@apply inline-flex justify-center px-3.5 py-2 text-sm font-medium text-white bg-indigo-600 border border-transparent rounded-md leading-5 transition hover:bg-indigo-700;
|
||||
}
|
||||
|
||||
.button[disabled] {
|
||||
|
|
@ -264,15 +293,15 @@ blockquote {
|
|||
}
|
||||
|
||||
.table-striped tbody tr:nth-child(odd) {
|
||||
background-color: #f1f5f8;
|
||||
background-color: var(--color-gray-100);
|
||||
}
|
||||
|
||||
.dark .table-striped tbody tr:nth-child(odd) {
|
||||
background-color: rgb(37 47 63);
|
||||
background-color: var(--color-gray-800);
|
||||
}
|
||||
|
||||
.dark .table-striped tbody tr:nth-child(even) {
|
||||
background-color: rgb(26 32 44);
|
||||
background-color: var(--color-gray-900);
|
||||
}
|
||||
|
||||
.fade-enter {
|
||||
|
|
@ -298,10 +327,6 @@ blockquote {
|
|||
background-color: inherit;
|
||||
}
|
||||
|
||||
.dark .fullwidth-shadow::before {
|
||||
box-shadow: 0 4px 2px -2px rgb(200 200 200 / 10%);
|
||||
}
|
||||
|
||||
iframe[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -316,10 +341,6 @@ iframe[hidden] {
|
|||
.date-option-group { }
|
||||
/* stylelint-enable */
|
||||
|
||||
.popper-tooltip {
|
||||
background-color: rgba(25 30 56);
|
||||
}
|
||||
|
||||
.tooltip-arrow,
|
||||
.tooltip-arrow::before {
|
||||
position: absolute;
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
.chartjs-tooltip {
|
||||
background-color: rgb(25 30 56);
|
||||
position: absolute;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
padding: 10px 12px;
|
||||
pointer-events: none;
|
||||
border-radius: 5px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
|
@ -12,10 +12,9 @@ import { useMountedEffect, useDebounce } from '../custom-hooks'
|
|||
|
||||
function Option({ isHighlighted, onClick, onMouseEnter, text, id }) {
|
||||
const className = classNames(
|
||||
'relative cursor-pointer select-none py-2 px-3',
|
||||
'relative cursor-pointer select-none py-2 px-3 text-gray-900 dark:text-gray-300',
|
||||
{
|
||||
'text-gray-900 dark:text-gray-300': !isHighlighted,
|
||||
'bg-indigo-600 text-white': isHighlighted
|
||||
'bg-gray-100 dark:bg-gray-700': isHighlighted
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -340,9 +339,10 @@ export default function PlausibleCombobox({
|
|||
}
|
||||
|
||||
const defaultBoxClass =
|
||||
'pl-2 pr-8 py-1 w-full dark:bg-gray-900 dark:text-gray-300 rounded-md shadow-xs border border-gray-300 dark:border-gray-700 focus-within:border-indigo-500 focus-within:ring-1 focus-within:ring-indigo-500'
|
||||
'pl-2 pr-8 py-1 w-full dark:bg-gray-750 dark:text-gray-300 rounded-md shadow-xs border border-gray-300 dark:border-gray-750'
|
||||
const finalBoxClass = classNames(boxClass || defaultBoxClass, {
|
||||
'border-indigo-500 ring-1 ring-indigo-500': isOpen
|
||||
'ring-3 ring-indigo-500/20 dark:ring-indigo-500/25 border !border-indigo-500':
|
||||
isOpen
|
||||
})
|
||||
|
||||
return (
|
||||
|
|
@ -365,7 +365,7 @@ export default function PlausibleCombobox({
|
|||
>
|
||||
<ul
|
||||
ref={listRef}
|
||||
className="z-50 absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1/5 ring-black focus:outline-hidden sm:text-sm dark:bg-gray-900"
|
||||
className="z-50 absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1/5 ring-black focus:outline-hidden sm:text-sm dark:bg-gray-800"
|
||||
>
|
||||
{renderDropDownContent()}
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export default function FilterOperatorSelector(props) {
|
|||
<BlurMenuButtonOnEscape targetRef={buttonRef} />
|
||||
<Popover.Button
|
||||
ref={buttonRef}
|
||||
className="relative flex justify-between items-center w-full rounded-md border border-gray-300 dark:border-gray-500 shadow-xs px-4 py-2 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-850 focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 dark:focus:ring-offset-gray-900 focus:ring-indigo-500 text-left"
|
||||
className="relative flex justify-between items-center w-full rounded-md border border-gray-300 dark:border-gray-750 px-4 py-2 bg-white dark:bg-gray-750 text-sm text-gray-700 dark:text-gray-200 dark:hover:bg-gray-700 focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 dark:focus:ring-offset-gray-900 focus:ring-indigo-500 text-left"
|
||||
>
|
||||
{FILTER_OPERATIONS_DISPLAY_NAMES[props.selectedType]}
|
||||
<ChevronDownIcon
|
||||
|
|
|
|||
|
|
@ -35,17 +35,18 @@ export function FeatureSetupNotice({
|
|||
|
||||
function renderCallToAction() {
|
||||
return (
|
||||
<a href={callToAction.link} className="ml-2 sm:ml-4 button px-2 sm:px-4">
|
||||
<p className="flex flex-col justify-center text-xs sm:text-sm">
|
||||
{callToAction.action}
|
||||
</p>
|
||||
<a
|
||||
href={callToAction.link}
|
||||
className="flex items-center gap-x-1.5 ml-2 sm:ml-4 button px-2 sm:px-4"
|
||||
>
|
||||
<p className="text-xs sm:text-sm font-medium">{callToAction.action}</p>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="ml-2 w-5 h-5"
|
||||
className="size-4"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
|
|
@ -61,7 +62,7 @@ export function FeatureSetupNotice({
|
|||
return (
|
||||
<button
|
||||
onClick={requestHideSection}
|
||||
className="inline-block px-2 sm:px-4 py-2 border border-gray-300 dark:border-gray-500 leading-5 rounded-md text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition ease-in-out duration-150"
|
||||
className="inline-block px-2 sm:px-4 py-2 font-medium leading-5 rounded-md border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-700 text-gray-800 dark:text-gray-100 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-white hover:shadow-sm transition-all duration-150"
|
||||
>
|
||||
Hide this report
|
||||
</button>
|
||||
|
|
@ -71,11 +72,11 @@ export function FeatureSetupNotice({
|
|||
return (
|
||||
<div className="sm:mx-32 mt-6 mb-3">
|
||||
<div className="py-3">
|
||||
<div className="text-center mt-2 text-gray-800 dark:text-gray-200">
|
||||
<div className="text-center text-pretty mt-2 text-gray-800 dark:text-gray-200 font-medium">
|
||||
{title}
|
||||
</div>
|
||||
|
||||
<div className="text-justify mt-4 font-small text-sm text-gray-500 dark:text-gray-200">
|
||||
<div className="text-center text-pretty mt-4 font-small text-sm text-gray-500 dark:text-gray-200">
|
||||
{info}
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,14 +32,15 @@ const panel = {
|
|||
|
||||
const toggleButton = {
|
||||
classNames: {
|
||||
rounded: 'flex items-center rounded text-sm leading-tight h-9',
|
||||
rounded:
|
||||
'flex items-center rounded text-sm leading-tight h-9 transition-all duration-150',
|
||||
shadow:
|
||||
'bg-white dark:bg-gray-800 shadow-sm text-gray-800 dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-900',
|
||||
'bg-white dark:bg-gray-750 shadow-sm text-gray-800 dark:text-gray-200 dark:hover:bg-gray-700',
|
||||
ghost:
|
||||
'text-gray-700 dark:text-gray-100 hover:bg-gray-200 dark:hover:bg-gray-900',
|
||||
truncatedText: 'truncate block font-medium',
|
||||
linkLike:
|
||||
'text-gray-700 dark:text-gray-300 hover:text-indigo-600 dark:hover:text-indigo-600'
|
||||
'text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100 transition-colors duration-150'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -54,12 +55,12 @@ const items = {
|
|||
hoverLink: classNames(
|
||||
'hover:bg-gray-100',
|
||||
'hover:text-gray-900',
|
||||
'dark:hover:bg-gray-900',
|
||||
'dark:hover:bg-gray-700',
|
||||
'dark:hover:text-gray-100',
|
||||
|
||||
'focus-within:bg-gray-100',
|
||||
'focus-within:text-gray-900',
|
||||
'dark:focus-within:bg-gray-900',
|
||||
'dark:focus-within:bg-gray-700',
|
||||
'dark:focus-within:text-gray-100'
|
||||
),
|
||||
roundedStart: 'first-of-type:rounded-t-md',
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ export const SearchInput = ({
|
|||
type="text"
|
||||
placeholder={isFocused ? placeholderFocused : placeholderUnfocused}
|
||||
className={classNames(
|
||||
'shadow-sm dark:bg-gray-900 dark:text-gray-100 focus:ring-indigo-500 focus:border-indigo-500 block border-gray-300 dark:border-gray-500 rounded-md dark:bg-gray-800 w-48',
|
||||
'dark:text-gray-100 block border-gray-300 dark:border-gray-750 rounded-md dark:bg-gray-750 w-48 dark:placeholder:text-gray-400 focus:outline-none focus:ring-3 focus:ring-indigo-500/20 dark:focus:ring-indigo-500/25 focus:border-indigo-500',
|
||||
className
|
||||
)}
|
||||
onChange={debouncedOnSearchInputChange}
|
||||
|
|
|
|||
|
|
@ -32,9 +32,10 @@ const TabButtonText = ({
|
|||
active: boolean
|
||||
}) => (
|
||||
<span
|
||||
className={classNames('truncate text-left', {
|
||||
'hover:text-indigo-600 cursor-pointer': !active,
|
||||
'text-indigo-700 dark:text-indigo-500 font-bold underline decoration-2 decoration-indigo-700 dark:decoration-indigo-500':
|
||||
className={classNames('truncate text-left transition-colors duration-150', {
|
||||
'hover:text-indigo-700 dark:hover:text-indigo-400 cursor-pointer':
|
||||
!active,
|
||||
'text-indigo-600 dark:text-indigo-500 font-bold underline decoration-2 decoration-indigo-600 dark:decoration-indigo-500':
|
||||
active
|
||||
})}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -97,11 +97,11 @@ export default function Funnel({ funnelName, tabs }) {
|
|||
const getPalette = () => {
|
||||
if (isDarkMode()) {
|
||||
return {
|
||||
dataLabelBackground: 'rgba(25, 30, 56, 0.97)',
|
||||
dataLabelTextColor: 'rgb(243, 244, 246)',
|
||||
dataLabelBackground: 'rgb(9, 9, 11)',
|
||||
dataLabelTextColor: 'rgb(244, 244, 245)',
|
||||
visitorsBackground: 'rgb(99, 102, 241)',
|
||||
dropoffBackground: '#2F3949',
|
||||
dropoffStripes: 'rgb(25, 30, 56)',
|
||||
dropoffBackground: 'rgb(63, 63, 70)',
|
||||
dropoffStripes: 'rgb(9, 9, 11)',
|
||||
stepNameLegendColor: 'rgb(228, 228, 231)',
|
||||
visitorsLegendClass: 'bg-indigo-500',
|
||||
dropoffLegendClass: 'bg-gray-600',
|
||||
|
|
@ -109,12 +109,12 @@ export default function Funnel({ funnelName, tabs }) {
|
|||
}
|
||||
} else {
|
||||
return {
|
||||
dataLabelBackground: 'rgba(25, 30, 56, 0.97)',
|
||||
dataLabelTextColor: 'rgb(243, 244, 246)',
|
||||
dataLabelBackground: 'rgb(39, 39, 42)',
|
||||
dataLabelTextColor: 'rgb(244, 244, 245)',
|
||||
visitorsBackground: 'rgb(99, 102, 241)',
|
||||
dropoffBackground: 'rgb(224, 231, 255)',
|
||||
dropoffStripes: 'rgb(255, 255, 255)',
|
||||
stepNameLegendColor: 'rgb(12, 24, 39)',
|
||||
stepNameLegendColor: 'rgb(24, 24, 27)',
|
||||
visitorsLegendClass: 'bg-indigo-500',
|
||||
dropoffLegendClass: 'bg-indigo-100',
|
||||
smallBarClass: 'bg-indigo-300'
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ function DashboardStats({
|
|||
updateImportedDataInView?: (v: boolean) => void
|
||||
}) {
|
||||
const statsBoxClass =
|
||||
'relative min-h-[436px] w-full mt-5 p-4 flex flex-col bg-white dark:bg-gray-825 shadow-sm rounded-md md:min-h-initial md:h-27.25rem md:w-[calc(50%-10px)] md:ml-[10px] md:mr-[10px] first:ml-0 last:mr-0'
|
||||
'relative min-h-[436px] w-full mt-5 p-4 flex flex-col bg-white dark:bg-gray-900 shadow-sm rounded-md md:min-h-initial md:h-27.25rem md:w-[calc(50%-10px)] md:ml-[10px] md:mr-[10px] first:ml-0 last:mr-0'
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ export function KeybindHint({
|
|||
return (
|
||||
<kbd
|
||||
className={classNames(
|
||||
'rounded border border-gray-200 dark:border-gray-600 px-2 font-mono font-normal text-xs text-gray-400',
|
||||
'rounded border border-gray-200 dark:border-gray-600 px-1.5 font-medium text-xs text-gray-400',
|
||||
className
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ const SeeMoreMenu = ({
|
|||
<div className="py-4 px-4">
|
||||
<AppliedFilterPillsList
|
||||
direction="vertical"
|
||||
pillClassName="dark:!shadow-gray-950/60"
|
||||
pillClassName="!shadow-none !bg-gray-100 dark:!bg-gray-700"
|
||||
slice={{
|
||||
type: 'no-render-outside',
|
||||
start: visibleFiltersCount
|
||||
|
|
@ -298,7 +298,7 @@ const SeeMoreMenu = ({
|
|||
/>
|
||||
</div>
|
||||
{showSomeActions && (
|
||||
<div className="mb-1 border-gray-200 dark:border-gray-500 border-b"></div>
|
||||
<div className="mb-1 border-gray-200 dark:border-gray-700 border-b"></div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
|
||||
export const MenuSeparator = () => (
|
||||
<div className="my-1 border-gray-200 dark:border-gray-500 border-b" />
|
||||
<div className="my-1 border-gray-200 dark:border-gray-700 border-b" />
|
||||
)
|
||||
|
|
|
|||
|
|
@ -37,10 +37,21 @@ const ArrowKeybind = ({
|
|||
)
|
||||
}
|
||||
|
||||
function ArrowIcon({ direction }: { direction: 'left' | 'right' }) {
|
||||
function ArrowIcon({
|
||||
direction,
|
||||
disabled = false
|
||||
}: {
|
||||
direction: 'left' | 'right'
|
||||
disabled?: boolean
|
||||
}) {
|
||||
return (
|
||||
<svg
|
||||
className="feather h-4 w-4"
|
||||
className={classNames(
|
||||
'feather size-4',
|
||||
disabled
|
||||
? 'text-gray-400 dark:text-gray-600'
|
||||
: 'text-gray-700 dark:text-gray-300'
|
||||
)}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
|
|
@ -74,14 +85,15 @@ export function MovePeriodArrows({ className }: { className?: string }) {
|
|||
const canGoForward =
|
||||
getDateForShiftedPeriod({ site, query, direction: 1 }) !== null
|
||||
|
||||
const sharedClass = 'flex items-center px-1 sm:px-2 dark:text-gray-100'
|
||||
const enabledClass = 'hover:bg-gray-100 dark:hover:bg-gray-900'
|
||||
const disabledClass = 'bg-gray-300 dark:bg-gray-950 cursor-not-allowed'
|
||||
const sharedClass =
|
||||
'flex items-center px-1 sm:px-2 dark:text-gray-100 transition-colors duration-150'
|
||||
const enabledClass = 'hover:bg-gray-100 dark:hover:bg-gray-700'
|
||||
const disabledClass = 'bg-gray-200 dark:bg-gray-850 cursor-not-allowed'
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'flex rounded shadow bg-white mr-2 sm:mr-4 cursor-pointer focus:z-10 dark:bg-gray-800',
|
||||
'flex rounded shadow bg-white mr-2 sm:mr-4 cursor-pointer focus:z-10 dark:bg-gray-750',
|
||||
className
|
||||
)}
|
||||
>
|
||||
|
|
@ -102,7 +114,7 @@ export function MovePeriodArrows({ className }: { className?: string }) {
|
|||
: (search) => search
|
||||
}
|
||||
>
|
||||
<ArrowIcon direction="left" />
|
||||
<ArrowIcon direction="left" disabled={!canGoBack} />
|
||||
</AppNavigationLink>
|
||||
<AppNavigationLink
|
||||
className={classNames(sharedClass, 'rounded-r', {
|
||||
|
|
@ -120,7 +132,7 @@ export function MovePeriodArrows({ className }: { className?: string }) {
|
|||
: (search) => search
|
||||
}
|
||||
>
|
||||
<ArrowIcon direction="right" />
|
||||
<ArrowIcon direction="right" disabled={!canGoForward} />
|
||||
</AppNavigationLink>
|
||||
{!!dashboardRouteMatch && <ArrowKeybind keyboardKey="ArrowLeft" />}
|
||||
{!!dashboardRouteMatch && <ArrowKeybind keyboardKey="ArrowRight" />}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ function TopBarStickyWrapper({ children }: { children: ReactNode }) {
|
|||
'relative top-0 py-2 sm:py-3 z-10',
|
||||
!site.embedded &&
|
||||
!inView &&
|
||||
'sticky fullwidth-shadow bg-gray-50 dark:bg-gray-850'
|
||||
'sticky fullwidth-shadow bg-gray-50 dark:bg-gray-950'
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -42,13 +42,13 @@ interface SegmentModalProps {
|
|||
const primaryNeutralButtonClassName = 'button !px-3'
|
||||
|
||||
const primaryNegativeButtonClassName = classNames(
|
||||
'button !px-3',
|
||||
'button !px-3.5',
|
||||
'items-center !bg-red-500 dark:!bg-red-500 hover:!bg-red-600 dark:hover:!bg-red-700 whitespace-nowrap'
|
||||
)
|
||||
|
||||
const secondaryButtonClassName = classNames(
|
||||
'button !px-3',
|
||||
'border !border-gray-300 dark:!border-gray-500 !text-gray-700 dark:!text-gray-300 !bg-transparent hover:!bg-gray-100 dark:hover:!bg-gray-850'
|
||||
'button !px-3.5',
|
||||
'border !border-gray-300 dark:!border-gray-700 !bg-white dark:!bg-gray-700 !text-gray-800 dark:!text-gray-100 hover:!text-gray-900 hover:!shadow-sm dark:hover:!bg-gray-600 dark:hover:!text-white'
|
||||
)
|
||||
|
||||
const SegmentActionModal = ({
|
||||
|
|
@ -200,7 +200,9 @@ export const DeleteSegmentModal = ({
|
|||
}
|
||||
|
||||
const FormTitle = ({ children }: { children?: ReactNode }) => (
|
||||
<h1 className="text-xl font-bold dark:text-gray-100 mb-2">{children}</h1>
|
||||
<h1 className="text-lg font-medium text-gray-900 dark:text-gray-100 leading-7 mb-8">
|
||||
{children}
|
||||
</h1>
|
||||
)
|
||||
|
||||
const ButtonsRow = ({
|
||||
|
|
@ -210,7 +212,7 @@ const ButtonsRow = ({
|
|||
className?: string
|
||||
children?: ReactNode
|
||||
}) => (
|
||||
<div className={classNames('mt-8 flex gap-x-4 items-center', className)}>
|
||||
<div className={classNames('mt-8 flex gap-x-3 items-center', className)}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
|
@ -228,7 +230,7 @@ const SegmentNameInput = ({
|
|||
<>
|
||||
<label
|
||||
htmlFor="name"
|
||||
className="block text-md font-medium text-gray-700 dark:text-gray-300"
|
||||
className="block mb-1.5 text-sm font-medium dark:text-gray-100 text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
Segment name
|
||||
</label>
|
||||
|
|
@ -238,7 +240,7 @@ const SegmentNameInput = ({
|
|||
onChange={(e) => onChange(e.target.value)}
|
||||
placeholder={namePlaceholder}
|
||||
id="name"
|
||||
className="block mt-2 p-2 w-full dark:bg-gray-900 dark:text-gray-300 rounded-md shadow-xs border border-gray-300 dark:border-gray-700 focus-within:border-indigo-500 focus-within:ring-1 focus-within:ring-indigo-500"
|
||||
className="block px-3.5 py-2.5 w-full text-sm dark:text-gray-300 rounded-md border border-gray-300 dark:border-gray-750 dark:bg-gray-750 focus:outline-none focus:ring-3 focus:ring-indigo-500/20 dark:focus:ring-indigo-500/25 focus:border-indigo-500"
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
|
@ -265,7 +267,7 @@ const SegmentTypeSelector = ({
|
|||
]
|
||||
|
||||
return (
|
||||
<div className="mt-4 flex flex-col gap-y-4">
|
||||
<div className="mt-6 flex flex-col gap-y-4">
|
||||
{options.map(({ type, name, description }) => (
|
||||
<div key={type}>
|
||||
<div className="flex">
|
||||
|
|
@ -275,14 +277,16 @@ const SegmentTypeSelector = ({
|
|||
type="radio"
|
||||
value=""
|
||||
onChange={() => onChange(type)}
|
||||
className="mt-4 w-4 h-4 text-indigo-600 bg-gray-100 border-gray-300 focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:border-gray-600"
|
||||
className="mt-px size-4.5 cursor-pointer text-indigo-600 dark:bg-transparent border-gray-400 dark:border-gray-600 checked:border-indigo-600 dark:checked:border-white"
|
||||
/>
|
||||
<label
|
||||
htmlFor={`segment-type-${type}`}
|
||||
className="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300"
|
||||
className="block ml-3 text-sm font-medium dark:text-gray-100 flex flex-col flex-inline"
|
||||
>
|
||||
<div className="font-bold">{name}</div>
|
||||
<div className="mt-1">{description}</div>
|
||||
<div>{name}</div>
|
||||
<div className="text-gray-500 dark:text-gray-400 mb-2 text-sm">
|
||||
{description}
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -531,7 +535,7 @@ export const SegmentModal = ({ id }: { id: SavedSegment['id'] }) => {
|
|||
{data?.segment_data ? SEGMENT_TYPE_LABELS[data.type] : false}
|
||||
</Placeholder>
|
||||
</div>
|
||||
<div className="my-4 border-b border-gray-300" />
|
||||
<div className="my-4 border-b border-gray-300 dark:border-gray-700" />
|
||||
{!!data?.segment_data && (
|
||||
<>
|
||||
<FiltersInSegment segment_data={data.segment_data} />
|
||||
|
|
|
|||
|
|
@ -347,7 +347,7 @@ export default function Behaviours({ importedDataInView }) {
|
|||
|
||||
return (
|
||||
<div className="items-start justify-between block w-full mt-6 md:flex relative">
|
||||
<div className="w-full p-4 bg-white rounded-md shadow-sm dark:bg-gray-825">
|
||||
<div className="w-full p-4 bg-white rounded-md shadow-sm dark:bg-gray-900">
|
||||
<div className="flex justify-between w-full">
|
||||
<div className="flex gap-x-1">
|
||||
<h3 className="font-bold dark:text-gray-100">
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ export default function Properties({ afterFetchData }) {
|
|||
: ''
|
||||
const comboboxValues = propKey ? [{ value: propKey, label: propKey }] : []
|
||||
const boxClass = classNames(
|
||||
'pl-2 pr-8 py-1 bg-transparent dark:text-gray-300 rounded-md shadow-sm border border-gray-300 dark:border-gray-500',
|
||||
'pl-2 pr-8 py-1 bg-transparent dark:text-gray-300 rounded-md shadow-sm border border-gray-300 dark:bg-gray-750 dark:border-gray-750',
|
||||
{
|
||||
'pointer-events-none': comboboxDisabled
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@ import { METRIC_LABELS, hasMultipleYears } from './graph-util'
|
|||
import { MetricFormatterShort } from '../reports/metric-formatter'
|
||||
import { ChangeArrow } from '../reports/change-arrow'
|
||||
|
||||
// Function to detect if dark mode is active
|
||||
const isDarkMode = () => {
|
||||
return document.documentElement.classList.contains('dark')
|
||||
}
|
||||
|
||||
const renderBucketLabel = function (
|
||||
query,
|
||||
graphData,
|
||||
|
|
@ -117,6 +122,9 @@ export default function GraphTooltip(graphData, metric, query) {
|
|||
tooltipRoot = createRoot(tooltipEl)
|
||||
}
|
||||
|
||||
const bgClass = isDarkMode() ? 'bg-gray-950' : 'bg-gray-800'
|
||||
tooltipEl.className = `absolute text-sm font-normal py-3 px-4 pointer-events-none rounded-md z-[100] min-w-[180px] ${bgClass}`
|
||||
|
||||
if (tooltipEl && offset && window.innerWidth < 768) {
|
||||
tooltipEl.style.top =
|
||||
offset.y + offset.height + window.scrollY + 15 + 'px'
|
||||
|
|
@ -139,9 +147,9 @@ export default function GraphTooltip(graphData, metric, query) {
|
|||
)
|
||||
|
||||
tooltipRoot.render(
|
||||
<aside className="text-gray-100 flex flex-col">
|
||||
<aside className="text-gray-100 flex flex-col gap-1.5">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="font-semibold mr-4 text-lg">
|
||||
<span className="font-semibold mr-4 text-xs uppercase">
|
||||
{METRIC_LABELS[metric]}
|
||||
</span>
|
||||
{tooltipData.comparisonDifference ? (
|
||||
|
|
@ -156,26 +164,24 @@ export default function GraphTooltip(graphData, metric, query) {
|
|||
|
||||
{tooltipData.label ? (
|
||||
<div className="flex flex-col">
|
||||
<div className="flex flex-row justify-between items-center">
|
||||
<div className="flex flex-row justify-between items-center text-sm">
|
||||
<span className="flex items-center mr-4">
|
||||
<div
|
||||
className="w-3 h-3 mr-1 rounded-full"
|
||||
className="size-2 mr-2 rounded-full"
|
||||
style={{ backgroundColor: 'rgba(101,116,205)' }}
|
||||
></div>
|
||||
<span>{tooltipData.label}</span>
|
||||
</span>
|
||||
<span className="text-base font-bold">
|
||||
{tooltipData.formattedValue}
|
||||
</span>
|
||||
<span className="font-bold">{tooltipData.formattedValue}</span>
|
||||
</div>
|
||||
|
||||
{tooltipData.comparisonLabel ? (
|
||||
<div className="flex flex-row justify-between items-center">
|
||||
<div className="flex flex-row justify-between items-center text-sm">
|
||||
<span className="flex items-center mr-4">
|
||||
<div className="w-3 h-3 mr-1 rounded-full bg-gray-500"></div>
|
||||
<div className="size-2 mr-2 rounded-full bg-gray-500"></div>
|
||||
<span>{tooltipData.comparisonLabel}</span>
|
||||
</span>
|
||||
<span className="text-base font-bold">
|
||||
<span className="font-bold">
|
||||
{tooltipData.formattedComparisonValue}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -183,12 +189,14 @@ export default function GraphTooltip(graphData, metric, query) {
|
|||
</div>
|
||||
) : null}
|
||||
|
||||
{graphData.interval === 'month' ? (
|
||||
<span className="font-semibold italic">Click to view month</span>
|
||||
) : null}
|
||||
{graphData.interval === 'day' ? (
|
||||
<span className="font-semibold italic">Click to view day</span>
|
||||
) : null}
|
||||
{['month', 'day'].includes(graphData.interval) && (
|
||||
<>
|
||||
<hr className="border-gray-600 dark:border-gray-800 my-1" />
|
||||
<span className="text-gray-300 dark:text-gray-400 text-xs">
|
||||
Click to view {graphData.interval}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,11 +84,14 @@ class LineGraph extends React.Component {
|
|||
suggestedMax: calculateMaximumY(dataSet),
|
||||
ticks: {
|
||||
callback: MetricFormatterShort[metric],
|
||||
color: this.props.darkTheme ? 'rgb(243, 244, 246)' : undefined
|
||||
color: this.props.darkTheme ? 'rgb(161, 161, 170)' : undefined
|
||||
},
|
||||
grid: {
|
||||
zeroLineColor: 'transparent',
|
||||
drawBorder: false
|
||||
drawBorder: false,
|
||||
color: this.props.darkTheme
|
||||
? 'rgba(39, 39, 42, 0.75)'
|
||||
: 'rgb(236, 236, 238)'
|
||||
}
|
||||
},
|
||||
yComparison: {
|
||||
|
|
@ -144,7 +147,7 @@ class LineGraph extends React.Component {
|
|||
shouldShowYear
|
||||
})(this.getLabelForValue(val))
|
||||
},
|
||||
color: this.props.darkTheme ? 'rgb(243, 244, 246)' : undefined
|
||||
color: this.props.darkTheme ? 'rgb(161, 161, 170)' : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ export default function TopStats({
|
|||
const statDisplayNameClass = classNames(
|
||||
'text-xs font-bold tracking-wide text-gray-500 uppercase dark:text-gray-400 whitespace-nowrap flex w-fit border-b',
|
||||
{
|
||||
'text-indigo-700 dark:text-indigo-500 border-indigo-700 dark:border-indigo-500':
|
||||
'text-indigo-600 dark:text-indigo-500 border-indigo-600 dark:border-indigo-500':
|
||||
isSelected,
|
||||
'group-hover:text-indigo-700 dark:group-hover:text-indigo-500 border-transparent':
|
||||
!isSelected
|
||||
|
|
@ -153,7 +153,7 @@ export default function TopStats({
|
|||
'px-4 md:px-6 w-1/2 my-4 lg:w-auto group select-none',
|
||||
{
|
||||
'cursor-pointer': canMetricBeGraphed(stat),
|
||||
'lg:border-l border-gray-300': index > 0,
|
||||
'lg:border-l border-gray-300 dark:border-gray-700': index > 0,
|
||||
'border-r lg:border-r-0': index % 2 === 0
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ export default function VisitorGraph({ updateImportedDataInView }) {
|
|||
return (
|
||||
<div
|
||||
className={
|
||||
'relative w-full mt-2 bg-white rounded-md shadow dark:bg-gray-825'
|
||||
'relative w-full mt-2 bg-white rounded-md shadow dark:bg-gray-900'
|
||||
}
|
||||
>
|
||||
{(topStatsLoading || graphLoading) && renderLoader()}
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ const WorldMap = ({
|
|||
|
||||
const colorScales = {
|
||||
[UIMode.dark]: ['#2e3954', '#6366f1'],
|
||||
[UIMode.light]: ['#f3ebff', '#a779e9']
|
||||
[UIMode.light]: ['#f5f3ff', '#a78bfa']
|
||||
}
|
||||
|
||||
const sharedCountryClass = classNames('transition-colors')
|
||||
|
|
@ -203,19 +203,19 @@ const sharedCountryClass = classNames('transition-colors')
|
|||
const countryClass = classNames(
|
||||
sharedCountryClass,
|
||||
'stroke-1',
|
||||
'fill-[#f8fafc]',
|
||||
'fill-[#fafafa]',
|
||||
'stroke-[#dae1e7]',
|
||||
'dark:fill-[#2d3747]',
|
||||
'dark:stroke-[#1f2937]'
|
||||
'dark:fill-[#323236]',
|
||||
'dark:stroke-[#18181b]'
|
||||
)
|
||||
|
||||
const highlightedCountryClass = classNames(
|
||||
sharedCountryClass,
|
||||
'stroke-2',
|
||||
'fill-[#f5f5f5]',
|
||||
'stroke-[#a779e9]',
|
||||
'dark:fill-[#374151]',
|
||||
'dark:stroke-[#4f46e5]'
|
||||
'fill-[#f4f4f5]',
|
||||
'stroke-[#a78bfa]',
|
||||
'dark:fill-[#3f3f46]',
|
||||
'dark:stroke-[#6366f1]'
|
||||
)
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export const BreakdownTable = <TListItem extends { name: string }>({
|
|||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="my-4 border-b border-gray-300"></div>
|
||||
<div className="my-4 border-b border-gray-300 dark:border-gray-700"></div>
|
||||
<div style={{ minHeight: `${MIN_HEIGHT_PX}px` }}>
|
||||
{displayError && status === 'error' && <ErrorMessage error={error} />}
|
||||
{isPending && <InitialLoadingSpinner />}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ class FilterModal extends React.Component {
|
|||
Filter by {formatFilterGroup(this.props.modalType)}
|
||||
</h1>
|
||||
|
||||
<div className="mt-4 border-b border-gray-300"></div>
|
||||
<div className="mt-4 border-b border-gray-300 dark:border-gray-700"></div>
|
||||
<main className="modal__content">
|
||||
<form
|
||||
className="flex flex-col"
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class Modal extends React.Component {
|
|||
<button className="modal__close"></button>
|
||||
<div
|
||||
ref={this.node}
|
||||
className="modal__container dark:bg-gray-800 focus:outline-hidden"
|
||||
className="modal__container dark:bg-gray-900 focus:outline-hidden"
|
||||
style={this.getStyle()}
|
||||
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
||||
tabIndex={0}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { addFilter } from '../../query'
|
|||
import { useQueryContext } from '../../query-context'
|
||||
import { useSiteContext } from '../../site-context'
|
||||
import { SortDirection } from '../../hooks/use-order-by'
|
||||
import { SourceFavicon } from '../sources/source-favicon'
|
||||
|
||||
function ReferrerDrilldownModal() {
|
||||
const { referrer } = useParams()
|
||||
|
|
@ -82,10 +83,9 @@ function ReferrerDrilldownModal() {
|
|||
|
||||
const renderIcon = useCallback((listItem) => {
|
||||
return (
|
||||
<img
|
||||
alt=""
|
||||
src={`/favicon/sources/${encodeURIComponent(listItem.name)}`}
|
||||
className="h-4 w-4 mr-2 align-middle inline"
|
||||
<SourceFavicon
|
||||
name={listItem.name}
|
||||
className="size-4 mr-2 align-middle inline"
|
||||
/>
|
||||
)
|
||||
}, [])
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import { addFilter } from '../../query'
|
|||
import { useQueryContext } from '../../query-context'
|
||||
import { useSiteContext } from '../../site-context'
|
||||
import { SortDirection } from '../../hooks/use-order-by'
|
||||
import { SourceFavicon } from '../sources/source-favicon'
|
||||
|
||||
const VIEWS = {
|
||||
sources: {
|
||||
|
|
@ -23,10 +24,9 @@ const VIEWS = {
|
|||
},
|
||||
renderIcon: (listItem) => {
|
||||
return (
|
||||
<img
|
||||
alt=""
|
||||
src={`/favicon/sources/${encodeURIComponent(listItem.name)}`}
|
||||
className="h-4 w-4 mr-2 align-middle inline"
|
||||
<SourceFavicon
|
||||
name={listItem.name}
|
||||
className="size-4 mr-2 align-middle inline"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export default function MoreLink({ linkProps, list, className, onClick }) {
|
|||
<div className={`w-full text-center ${className ? className : ''}`}>
|
||||
<AppNavigationLink
|
||||
{...linkProps}
|
||||
className="leading-snug font-bold text-sm text-gray-500 dark:text-gray-400 hover:text-red-500 dark:hover:text-red-400 transition tracking-wide"
|
||||
className="leading-snug font-bold text-sm text-gray-500 dark:text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors duration-150 tracking-wide"
|
||||
onClick={onClick}
|
||||
>
|
||||
{detailsIcon()}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import ImportedQueryUnsupportedWarning from '../../stats/imported-query-unsuppor
|
|||
import { useQueryContext } from '../../query-context'
|
||||
import { useSiteContext } from '../../site-context'
|
||||
import { referrersDrilldownRoute } from '../../router'
|
||||
import { SourceFavicon } from './source-favicon'
|
||||
|
||||
const NO_REFERRER = 'Direct / None'
|
||||
|
||||
|
|
@ -52,11 +53,9 @@ export default function Referrers({ source }) {
|
|||
|
||||
function renderIcon(listItem) {
|
||||
return (
|
||||
<img
|
||||
alt=""
|
||||
src={`/favicon/sources/${encodeURIComponent(listItem.name)}`}
|
||||
referrerPolicy="no-referrer"
|
||||
className="inline w-4 h-4 mr-2 -mt-px align-middle"
|
||||
<SourceFavicon
|
||||
name={listItem.name}
|
||||
className="inline size-4 mr-2 -mt-px align-middle"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
import React from 'react'
|
||||
import classNames from 'classnames'
|
||||
|
||||
interface SourceFaviconProps {
|
||||
name: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
export const SourceFavicon = ({ name, className }: SourceFaviconProps) => {
|
||||
const sourceName = name.toLowerCase()
|
||||
const needsWhiteBg =
|
||||
sourceName.includes('github') || sourceName.includes('chatgpt.com')
|
||||
|
||||
return (
|
||||
<img
|
||||
alt=""
|
||||
src={`/favicon/sources/${encodeURIComponent(name)}`}
|
||||
referrerPolicy="no-referrer"
|
||||
className={classNames(
|
||||
className,
|
||||
needsWhiteBg &&
|
||||
'dark:bg-white dark:border dark:border-white dark:rounded-full'
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ import {
|
|||
import ImportedQueryUnsupportedWarning from '../imported-query-unsupported-warning'
|
||||
import { useQueryContext } from '../../query-context'
|
||||
import { useSiteContext } from '../../site-context'
|
||||
import { SourceFavicon } from './source-favicon'
|
||||
import {
|
||||
sourcesRoute,
|
||||
channelsRoute,
|
||||
|
|
@ -63,13 +64,7 @@ function AllSources({ afterFetchData }) {
|
|||
}
|
||||
|
||||
function renderIcon(listItem) {
|
||||
return (
|
||||
<img
|
||||
alt=""
|
||||
src={`/favicon/sources/${encodeURIComponent(listItem.name)}`}
|
||||
className="w-4 h-4 mr-2"
|
||||
/>
|
||||
)
|
||||
return <SourceFavicon name={listItem.name} className="size-4 mr-2" />
|
||||
}
|
||||
|
||||
function chooseMetrics() {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ function TooltipMessage({
|
|||
ref={setPopperElement}
|
||||
style={popperStyle}
|
||||
{...popperAttributes}
|
||||
className="z-50 p-2 rounded-sm text-sm text-gray-100 font-bold popper-tooltip"
|
||||
className="z-50 p-2 rounded-sm text-sm text-gray-100 font-bold bg-gray-800 dark:bg-gray-700"
|
||||
role="tooltip"
|
||||
>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ defmodule PlausibleWeb.CustomerSupport.Team.Components.Audit do
|
|||
class="float-right pt-4 text-sm"
|
||||
>
|
||||
← Return
|
||||
<kbd class="rounded border border-gray-200 dark:border-gray-600 px-2 font-mono font-normal text-xs text-gray-400">
|
||||
<kbd class="rounded border border-gray-200 dark:border-gray-600 px-1.5 font-medium text-xs text-gray-400">
|
||||
ESC
|
||||
</kbd>
|
||||
</.styled_link>
|
||||
|
|
@ -131,7 +131,7 @@ defmodule PlausibleWeb.CustomerSupport.Team.Components.Audit do
|
|||
phx-value-before={@audit_page.metadata.before}
|
||||
phx-value-limit={@current_limit}
|
||||
phx-target={@myself}
|
||||
theme="bright"
|
||||
theme="secondary"
|
||||
>
|
||||
← Prev
|
||||
</.button>
|
||||
|
|
@ -143,7 +143,7 @@ defmodule PlausibleWeb.CustomerSupport.Team.Components.Audit do
|
|||
phx-value-after={@audit_page.metadata.after}
|
||||
phx-value-limit={@current_limit}
|
||||
phx-target={@myself}
|
||||
theme="bright"
|
||||
theme="secondary"
|
||||
>
|
||||
Next →
|
||||
</.button>
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ defmodule PlausibleWeb.CustomerSupport.Team.Components.Billing do
|
|||
value={@cost_estimate}
|
||||
/>
|
||||
|
||||
<.button theme="bright" phx-click="hide-plan-form" phx-target={@myself}>
|
||||
<.button theme="secondary" phx-click="hide-plan-form" phx-target={@myself}>
|
||||
Cancel
|
||||
</.button>
|
||||
|
||||
|
|
|
|||
|
|
@ -64,10 +64,10 @@ defmodule PlausibleWeb.Live.FunnelSettings.Form do
|
|||
phx-target="#funnel-form"
|
||||
phx-click-away="cancel-add-funnel"
|
||||
onkeydown="return event.key != 'Enter';"
|
||||
class="bg-white dark:bg-gray-800 shadow-md rounded px-8 pt-6 pb-8 mb-4 mt-8"
|
||||
class="bg-white dark:bg-gray-900 shadow-md rounded px-8 pt-6 pb-8 mb-4 mt-8"
|
||||
>
|
||||
<.title class="mb-6">
|
||||
{if @funnel, do: "Edit", else: "Add"} Funnel
|
||||
{if @funnel, do: "Edit", else: "Add"} funnel
|
||||
</.title>
|
||||
|
||||
<.input
|
||||
|
|
@ -76,12 +76,12 @@ defmodule PlausibleWeb.Live.FunnelSettings.Form do
|
|||
autocomplete="off"
|
||||
placeholder="e.g. From Blog to Purchase"
|
||||
autofocus
|
||||
label="Funnel Name"
|
||||
label="Funnel name"
|
||||
/>
|
||||
|
||||
<div id="steps-builder" class="mt-6">
|
||||
<.label>
|
||||
Funnel Steps
|
||||
Funnel steps
|
||||
</.label>
|
||||
|
||||
<div :for={step_idx <- @step_ids} class="flex mb-3 mt-3">
|
||||
|
|
@ -139,7 +139,7 @@ defmodule PlausibleWeb.Live.FunnelSettings.Form do
|
|||
length(@step_ids) > map_size(@selections_made)
|
||||
}
|
||||
>
|
||||
<span>{if @funnel, do: "Update", else: "Add"} Funnel</span>
|
||||
<span>{if @funnel, do: "Update", else: "Add"} funnel</span>
|
||||
</.button>
|
||||
</div>
|
||||
</.form>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ defmodule PlausibleWeb.Live.FunnelSettings.List do
|
|||
<div>
|
||||
<.filter_bar filter_text={@filter_text} placeholder="Search Funnels">
|
||||
<.button id="add-funnel-button" phx-click="add-funnel" mt?={false}>
|
||||
Add Funnel
|
||||
Add funnel
|
||||
</.button>
|
||||
</.filter_bar>
|
||||
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ defmodule PlausibleWeb.Components.Billing do
|
|||
def usage_and_limits_table(assigns) do
|
||||
~H"""
|
||||
<table class="min-w-full text-gray-900 dark:text-gray-100" {@rest}>
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-gray-600">
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-gray-700">
|
||||
{render_slot(@inner_block)}
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -209,7 +209,7 @@ defmodule PlausibleWeb.Components.Billing do
|
|||
~H"""
|
||||
<div
|
||||
id="monthly-quota-box"
|
||||
class="w-full flex-1 h-32 px-2 py-4 text-center bg-gray-100 rounded-sm dark:bg-gray-900 w-max-md"
|
||||
class="w-full flex-1 h-32 px-2 py-4 text-center bg-gray-100 rounded-sm dark:bg-gray-800 w-max-md"
|
||||
>
|
||||
<h4 class="font-black dark:text-gray-100">Monthly quota</h4>
|
||||
<div class="py-2 text-xl font-medium dark:text-gray-100">
|
||||
|
|
@ -276,7 +276,7 @@ defmodule PlausibleWeb.Components.Billing do
|
|||
id={@id}
|
||||
onclick={"if (#{@confirmed}) {#{@js_action_expr}}"}
|
||||
class={[
|
||||
"text-sm w-full mt-6 block rounded-md py-2 px-3 text-center font-semibold leading-6 text-white",
|
||||
"text-sm w-full mt-6 block rounded-md py-2 px-3 text-center font-semibold leading-6 text-white transition-colors duration-150",
|
||||
!@checkout_disabled && "bg-indigo-600 hover:bg-indigo-500",
|
||||
@checkout_disabled && "pointer-events-none bg-gray-400 dark:bg-gray-600"
|
||||
]}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
|
|||
<div
|
||||
id={"#{@kind}-plan-box"}
|
||||
class={[
|
||||
"shadow-lg border border-gray-200 dark:border-none bg-white rounded-xl px-6 sm:px-4 py-4 sm:py-3 dark:bg-gray-800",
|
||||
"shadow-lg border border-gray-200 dark:border-none bg-white rounded-xl px-6 sm:px-4 py-4 sm:py-3 dark:bg-gray-850",
|
||||
!@highlight && "dark:ring-gray-600",
|
||||
@highlight && "ring-2 ring-indigo-600 dark:ring-indigo-300"
|
||||
]}
|
||||
|
|
@ -63,7 +63,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
|
|||
<div
|
||||
id="enterprise-plan-box"
|
||||
class={[
|
||||
"rounded-xl px-6 sm:px-4 py-4 sm:py-3 bg-gray-900 shadow-xl dark:bg-gray-800",
|
||||
"rounded-xl px-6 sm:px-4 py-4 sm:py-3 bg-gray-900 shadow-xl dark:bg-gray-850",
|
||||
!@recommended && "dark:ring-gray-600",
|
||||
@recommended && "ring-4 ring-indigo-500 dark:ring-2 dark:ring-indigo-300"
|
||||
]}
|
||||
|
|
@ -197,7 +197,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
|
|||
|
||||
<span
|
||||
id={"#{@kind}-price-tag-interval"}
|
||||
class="text-sm font-semibold leading-6 text-gray-600 pl-1 self-end"
|
||||
class="text-sm font-semibold leading-6 text-gray-600 dark:text-gray-500 pl-1 self-end"
|
||||
>
|
||||
/year
|
||||
</span>
|
||||
|
|
@ -205,7 +205,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
|
|||
<div class="font-bold tracking-tight text-sm self-center">
|
||||
<span
|
||||
id={"#{@kind}-discount-price-tag-strikethrough-amount"}
|
||||
class="line-through tracking-tight text-gray-500 dark:text-gray-600"
|
||||
class="line-through tracking-tight text-gray-500"
|
||||
>
|
||||
{@monthly_cost}
|
||||
</span>
|
||||
|
|
@ -214,7 +214,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
|
|||
</span>
|
||||
</div>
|
||||
|
||||
<span class="text-sm font-semibold text-gray-600 pl-1 self-center">
|
||||
<span class="text-sm font-semibold text-gray-600 dark:text-gray-500 pl-1 self-center">
|
||||
/month
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -26,19 +26,19 @@ defmodule PlausibleWeb.Components.FlowProgress do
|
|||
<div class="flex items-center text-base">
|
||||
<div
|
||||
:if={idx < @current_step_idx}
|
||||
class="w-5 h-5 bg-green-500 dark:bg-green-600 text-white rounded-full flex items-center justify-center"
|
||||
class="size-6 bg-green-500 dark:bg-green-600 text-white rounded-full flex items-center justify-center"
|
||||
>
|
||||
<Heroicons.check class="w-4 h-4" />
|
||||
<Heroicons.check class="size-4" />
|
||||
</div>
|
||||
<div
|
||||
:if={idx == @current_step_idx}
|
||||
class="w-5 h-5 bg-indigo-600 text-white rounded-full flex items-center justify-center font-semibold"
|
||||
class="size-6 bg-indigo-600 text-xs text-white font-bold rounded-full flex items-center justify-center"
|
||||
>
|
||||
{idx + 1}
|
||||
</div>
|
||||
<div
|
||||
:if={idx > @current_step_idx}
|
||||
class="w-5 h-5 bg-gray-300 text-white dark:bg-gray-800 rounded-full flex items-center justify-center"
|
||||
class="size-6 bg-gray-300 text-xs text-white font-bold dark:bg-gray-800 rounded-full flex items-center justify-center"
|
||||
>
|
||||
{idx + 1}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
|
||||
@notice_themes %{
|
||||
gray: %{
|
||||
bg: "bg-gray-150 dark:bg-gray-700/50",
|
||||
bg: "bg-gray-100 dark:bg-gray-800",
|
||||
icon: "text-gray-600 dark:text-gray-300",
|
||||
title_text: "text-sm text-gray-900 dark:text-gray-100",
|
||||
body_text: "text-sm text-gray-600 dark:text-gray-300 leading-5"
|
||||
|
|
@ -18,22 +18,23 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
body_text: "text-sm text-gray-600 dark:text-gray-100/60 leading-5"
|
||||
},
|
||||
red: %{
|
||||
bg: "bg-red-100 dark:bg-red-900/50",
|
||||
icon: "text-red-600",
|
||||
bg: "bg-red-100 dark:bg-red-900/30",
|
||||
icon: "text-red-600 dark:text-red-500",
|
||||
title_text: "text-sm text-gray-900 dark:text-gray-100",
|
||||
body_text: "text-sm text-gray-600 dark:text-gray-100/60 leading-5"
|
||||
}
|
||||
}
|
||||
|
||||
@button_themes %{
|
||||
"primary" => "bg-indigo-600 text-white hover:bg-indigo-700 focus-visible:outline-indigo-600",
|
||||
"bright" =>
|
||||
"border border-gray-200 bg-gray-100 dark:bg-gray-300 text-gray-800 hover:bg-gray-200 focus-visible:outline-gray-100",
|
||||
"primary" =>
|
||||
"bg-indigo-600 text-white hover:bg-indigo-700 focus-visible:outline-indigo-600 disabled:bg-indigo-400/60 disabled:dark:bg-indigo-600/30 disabled:dark:text-white/35",
|
||||
"secondary" =>
|
||||
"border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-700 text-gray-800 dark:text-gray-100 hover:text-gray-900 hover:shadow-sm dark:hover:bg-gray-600 dark:hover:text-white disabled:text-gray-700/40 disabled:hover:shadow-none dark:disabled:text-gray-500 dark:disabled:bg-gray-800 dark:disabled:border-gray-800",
|
||||
"danger" =>
|
||||
"border border-gray-300 dark:border-gray-500 text-red-700 bg-white dark:bg-gray-900 hover:text-red-500 dark:hover:text-red-400 focus:border-blue-300 dark:text-red-500 active:text-red-800"
|
||||
"border border-gray-300 dark:border-gray-800 text-red-600 bg-white dark:bg-gray-800 hover:text-red-700 hover:shadow-sm dark:hover:text-red-400 dark:text-red-500 active:text-red-800 disabled:text-red-700/40 disabled:hover:shadow-none dark:disabled:text-red-500/35 dark:disabled:bg-gray-800"
|
||||
}
|
||||
|
||||
@button_base_class "whitespace-nowrap truncate inline-flex items-center justify-center gap-x-2 font-medium rounded-md px-3.5 py-2.5 text-sm shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:bg-gray-400 dark:disabled:text-white dark:disabled:text-gray-400 dark:disabled:bg-gray-700"
|
||||
@button_base_class "whitespace-nowrap truncate inline-flex items-center justify-center gap-x-2 font-medium rounded-md px-3.5 py-2.5 text-sm transition-all duration-150 cursor-pointer disabled:cursor-not-allowed"
|
||||
|
||||
attr(:type, :string, default: "button")
|
||||
attr(:theme, :string, default: "primary")
|
||||
|
|
@ -94,7 +95,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
|
||||
theme_class =
|
||||
if assigns.disabled do
|
||||
"bg-gray-400 text-white dark:text-white dark:text-gray-400 dark:bg-gray-700 cursor-not-allowed"
|
||||
"bg-gray-400 text-white transition-colors duration-150 dark:text-white dark:text-gray-400 dark:bg-gray-700 cursor-not-allowed"
|
||||
else
|
||||
@button_themes[assigns.theme]
|
||||
end
|
||||
|
|
@ -141,7 +142,12 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
<:tooltip_content>
|
||||
<span>Learn more</span>
|
||||
</:tooltip_content>
|
||||
<a href={"https://plausible.io/docs/#{@slug}"} rel="noopener noreferrer" target="_blank">
|
||||
<a
|
||||
href={"https://plausible.io/docs/#{@slug}"}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
class="inline-block"
|
||||
>
|
||||
<Heroicons.information_circle class="text-gray-400 dark:text-indigo-500 size-5 hover:text-indigo-500 dark:hover:text-indigo-400 transition-colors duration-150" />
|
||||
</a>
|
||||
</.tooltip>
|
||||
|
|
@ -157,9 +163,9 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
|
||||
def upgrade(assigns) do
|
||||
~H"""
|
||||
<div class={["rounded-md p-5 bg-gray-100 dark:bg-gray-700/50", @class]} {@rest}>
|
||||
<div class={["rounded-md p-5 bg-gray-100 dark:bg-gray-800", @class]} {@rest}>
|
||||
<div class="flex flex-col gap-y-4">
|
||||
<div class="flex-shrink-0 bg-white dark:bg-gray-700 max-w-max rounded-md p-2 border border-gray-200 dark:border-gray-600 text-indigo-500 dark:text-indigo-400">
|
||||
<div class="flex-shrink-0 bg-white dark:bg-gray-700 max-w-max rounded-md p-2 border border-gray-200 dark:border-gray-600 text-indigo-500">
|
||||
{render_slot(@icon)}
|
||||
</div>
|
||||
<div class="flex flex-col gap-y-2">
|
||||
|
|
@ -315,7 +321,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
slot(:inner_block, required: true)
|
||||
|
||||
@base_class "block rounded-md text-sm/6 text-gray-900 ui-disabled:text-gray-500 dark:text-gray-100 dark:ui-disabled:text-gray-400 px-3 py-1.5"
|
||||
@clickable_class "hover:bg-gray-100 dark:hover:bg-gray-700"
|
||||
@clickable_class "hover:bg-gray-100 dark:hover:bg-gray-700/80"
|
||||
def dropdown_item(assigns) do
|
||||
assigns =
|
||||
if assigns[:disabled] do
|
||||
|
|
@ -451,12 +457,12 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
>
|
||||
<span
|
||||
class="relative inline-flex h-6 w-11 shrink-0 rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-hidden focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2"
|
||||
x-bind:class={"#{@js_active_var} ? 'bg-indigo-600' : 'dark:bg-gray-700 bg-gray-200'"}
|
||||
x-bind:class={"#{@js_active_var} ? 'bg-indigo-600' : 'dark:bg-gray-600 bg-gray-200'"}
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow-sm ring-0 transition duration-200 ease-in-out"
|
||||
x-bind:class={"#{@js_active_var} ? 'dark:bg-gray-800 translate-x-5' : 'dark:bg-gray-800 translate-x-0'"}
|
||||
class="pointer-events-none inline-block size-5 transform rounded-full bg-white shadow-sm ring-0 transition duration-200 ease-in-out"
|
||||
x-bind:class={"#{@js_active_var} ? 'dark:bg-white translate-x-5' : 'dark:bg-white translate-x-0'"}
|
||||
/>
|
||||
</span>
|
||||
</button>
|
||||
|
|
@ -484,7 +490,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
|
||||
def tile(assigns) do
|
||||
~H"""
|
||||
<div class="shadow-sm bg-white dark:bg-gray-800 rounded-md mb-6">
|
||||
<div class="shadow-sm bg-white dark:bg-gray-900 rounded-md mb-6">
|
||||
<header class="relative py-4 px-6">
|
||||
<.title>
|
||||
{render_slot(@title)}
|
||||
|
|
@ -542,10 +548,8 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
"top-0",
|
||||
"-translate-y-full",
|
||||
"z-[1000]",
|
||||
"sm:min-w-48",
|
||||
"sm:max-w-72",
|
||||
"whitespace-normal",
|
||||
"break-words"
|
||||
"w-max"
|
||||
]
|
||||
|
||||
tooltip_position_classes =
|
||||
|
|
@ -582,7 +586,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
>
|
||||
<div class="bg-gray-900 text-white rounded-sm px-2.5 py-1.5 text-xs font-medium">
|
||||
<div class="bg-gray-800 text-white rounded-sm px-2.5 py-1.5 text-xs font-medium">
|
||||
{render_slot(@tooltip_content)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -700,7 +704,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
def focus_box(assigns) do
|
||||
~H"""
|
||||
<div
|
||||
class="bg-white w-full max-w-lg mx-auto dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-md rounded-md mt-12"
|
||||
class="bg-white w-full max-w-lg mx-auto dark:bg-gray-900 text-gray-900 dark:text-gray-100 shadow-md rounded-md mt-12"
|
||||
{@rest}
|
||||
>
|
||||
<div class={if(@padding?, do: "p-8")}>
|
||||
|
|
@ -725,7 +729,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
:if={@footer != []}
|
||||
class="flex flex-col dark:text-gray-200 border-t border-gray-300 dark:border-gray-700"
|
||||
>
|
||||
<div class="p-8">
|
||||
<div class="p-8 text-sm">
|
||||
{render_slot(@footer)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -832,8 +836,8 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
<button
|
||||
type="submit"
|
||||
class={[
|
||||
"relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full transition-colors ease-in-out duration-200 focus:outline-none focus:ring",
|
||||
if(@set_to, do: "bg-indigo-600", else: "bg-gray-200 dark:bg-gray-700"),
|
||||
"relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full transition-colors ease-in-out duration-200",
|
||||
if(@set_to, do: "bg-indigo-600", else: "bg-gray-200 dark:bg-gray-600"),
|
||||
if(@disabled?, do: "cursor-not-allowed")
|
||||
]}
|
||||
disabled={@disabled?}
|
||||
|
|
@ -841,7 +845,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
<span
|
||||
aria-hidden="true"
|
||||
class={[
|
||||
"inline-block h-5 w-5 rounded-full bg-white dark:bg-gray-800 shadow transform transition ease-in-out duration-200",
|
||||
"inline-block size-5 rounded-full bg-white shadow transform transition ease-in-out duration-200",
|
||||
if(@set_to, do: "translate-x-5", else: "translate-x-0")
|
||||
]}
|
||||
/>
|
||||
|
|
@ -920,7 +924,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
def filter_bar(assigns) do
|
||||
~H"""
|
||||
<div class="mb-6 flex items-center justify-between" x-data>
|
||||
<div :if={@filtering_enabled?} class="relative rounded-md shadow-xs flex">
|
||||
<div :if={@filtering_enabled?} class="relative rounded-md flex">
|
||||
<form id="filter-form" phx-change="filter" phx-submit="filter" class="flex items-center">
|
||||
<div class="text-gray-800 inline-flex items-center">
|
||||
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
||||
|
|
@ -930,7 +934,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
type="text"
|
||||
name="filter-text"
|
||||
id="filter-text"
|
||||
class="w-36 sm:w-full pl-8 text-sm shadow-xs dark:bg-gray-900 dark:text-gray-300 focus:ring-indigo-500 focus:border-indigo-500 block border-gray-300 dark:border-gray-500 rounded-md dark:bg-gray-800"
|
||||
class="w-36 sm:w-full pl-8 text-sm dark:bg-gray-750 dark:text-gray-300 focus:ring-indigo-500 focus:border-indigo-500 block border-gray-300 dark:border-gray-750 rounded-md dark:placeholder:text-gray-400 focus:outline-none focus:ring-3 focus:ring-indigo-500/20 dark:focus:ring-indigo-500/25 focus:border-indigo-500"
|
||||
placeholder="Press / to search"
|
||||
x-ref="filter_text"
|
||||
phx-debounce={200}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ defmodule PlausibleWeb.Components.Layout do
|
|||
<% else %>
|
||||
<.settings_tab icon={@icon} text={@text} />
|
||||
|
||||
<div class="ml-6">
|
||||
<div class="flex flex-col gap-0.5 ml-7">
|
||||
<.settings_tab
|
||||
:for={%{key: key, value: value} = opts <- @value}
|
||||
selected_fn={@selected_fn}
|
||||
|
|
@ -128,9 +128,9 @@ defmodule PlausibleWeb.Components.Layout do
|
|||
class={[
|
||||
"text-sm flex items-center px-2 py-2 leading-5 font-medium rounded-md outline-none focus:outline-none transition ease-in-out duration-150",
|
||||
@current_tab? &&
|
||||
"text-gray-900 dark:text-gray-100 bg-gray-150 font-semibold dark:bg-gray-700/50 hover:text-gray-900 dark:hover:text-gray-100 focus:bg-gray-200 dark:focus:bg-gray-800",
|
||||
"text-gray-900 dark:text-gray-100 bg-gray-150 font-semibold dark:bg-gray-850 hover:text-gray-900 dark:hover:text-gray-100 focus:bg-gray-200 dark:focus:bg-gray-800",
|
||||
@value && not @current_tab? &&
|
||||
"text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-800 focus:text-gray-900 focus:bg-gray-50 dark:focus:text-gray-100 dark:focus:bg-gray-800",
|
||||
"text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-850 focus:text-gray-900 focus:bg-gray-50 dark:focus:text-gray-100 dark:focus:bg-gray-800",
|
||||
!@value && "text-gray-600 dark:text-gray-300"
|
||||
]}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ defmodule PlausibleWeb.Components.TwoFactor do
|
|||
type="button"
|
||||
x-on:click={"#{@state_param} = false"}
|
||||
class="w-full sm:w-auto mr-2"
|
||||
theme="bright"
|
||||
theme="secondary"
|
||||
>
|
||||
Cancel
|
||||
</.button>
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ defmodule PlausibleWeb.Live.ChoosePlan do
|
|||
<div class="mt-6 w-full md:flex">
|
||||
<a
|
||||
href={Routes.settings_path(PlausibleWeb.Endpoint, :subscription)}
|
||||
class="hidden md:flex md:w-1/6 h-max md:mt-2 text-indigo-600 hover:text-indigo-700 dark:text-indigo-500 dark:hover:text-indigo-600 text-sm font-semibold gap-1 items-center"
|
||||
class="hidden md:flex md:w-1/6 h-max md:mt-2 text-indigo-600 hover:text-indigo-700 dark:text-indigo-500 dark:hover:text-indigo-400 text-sm font-semibold gap-1 items-center transition-colors duration-150"
|
||||
>
|
||||
<span>←</span>
|
||||
<p>Back to settings</p>
|
||||
|
|
@ -222,7 +222,7 @@ defmodule PlausibleWeb.Live.ChoosePlan do
|
|||
title="What's my current usage?"
|
||||
title_class="text-gray-900 dark:text-gray-200"
|
||||
>
|
||||
<p class="text-gray-600 dark:text-gray-300">
|
||||
<p class="text-gray-600 dark:text-gray-400">
|
||||
<.render_usage pageview_usage={@usage.monthly_pageviews} />
|
||||
</p>
|
||||
</.accordion_item>
|
||||
|
|
@ -232,7 +232,7 @@ defmodule PlausibleWeb.Live.ChoosePlan do
|
|||
title="What happens if I go over my monthly pageview limit?"
|
||||
title_class="text-gray-900 dark:text-gray-200"
|
||||
>
|
||||
<p class="text-gray-600 dark:text-gray-300">
|
||||
<p class="text-gray-600 dark:text-gray-400">
|
||||
You will never be charged extra for an occasional traffic spike. There are no surprise fees and your card will never be charged unexpectedly. If your pageviews exceed your plan for two consecutive months, we will contact you to upgrade to a higher plan for the following month. You will have two weeks to make a decision. You can decide to continue with a higher plan or to cancel your account at that point.
|
||||
</p>
|
||||
</.accordion_item>
|
||||
|
|
@ -258,7 +258,7 @@ defmodule PlausibleWeb.Live.ChoosePlan do
|
|||
</span>
|
||||
Please see your full usage report (including sites and team members) under the
|
||||
<a
|
||||
class="text-indigo-600 inline hover:underline"
|
||||
class="inline font-medium text-indigo-600 dark:text-indigo-500 hover:text-indigo-700 dark:hover:text-indigo-400 transition-colors duration-150"
|
||||
href={Routes.settings_path(PlausibleWeb.Endpoint, :subscription)}
|
||||
>
|
||||
"Subscription" section
|
||||
|
|
@ -361,8 +361,19 @@ defmodule PlausibleWeb.Live.ChoosePlan do
|
|||
~H"""
|
||||
<div class="mt-16 -mb-16 text-center">
|
||||
Any other questions?
|
||||
<a class="text-indigo-600 hover:underline" href={contact_link()}>Contact us</a>
|
||||
or see <a class="text-indigo-600 hover:underline" href={billing_faq_link()}>billing FAQ</a>
|
||||
<a
|
||||
class="font-medium text-indigo-600 hover:text-indigo-700 dark:text-indigo-500 dark:hover:text-indigo-400 transition-colors duration-150"
|
||||
href={contact_link()}
|
||||
>
|
||||
Contact us
|
||||
</a>
|
||||
or see
|
||||
<a
|
||||
class="font-medium text-indigo-600 hover:text-indigo-700 dark:text-indigo-500 dark:hover:text-indigo-400 transition-colors duration-150"
|
||||
href={billing_faq_link()}
|
||||
>
|
||||
billing FAQ
|
||||
</a>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ defmodule PlausibleWeb.Live.Components.ComboBox do
|
|||
<div class="relative w-full">
|
||||
<div
|
||||
@click.away="close"
|
||||
class="pl-2 pr-8 py-1 w-full dark:bg-gray-900 dark:text-gray-300 rounded-md shadow-xs border border-gray-300 dark:border-gray-700 focus-within:border-indigo-500 focus-within:ring-1 focus-within:ring-indigo-500"
|
||||
class="pl-2 pr-8 py-1 w-full dark:bg-gray-750 dark:text-gray-300 rounded-md shadow-xs border border-gray-300 dark:border-gray-750 focus-within:outline-none focus-within:ring-3 focus-within:ring-indigo-500/20 dark:focus-within:ring-indigo-500/25 focus-within:border-indigo-500"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
|
|
@ -180,7 +180,7 @@ defmodule PlausibleWeb.Live.Components.ComboBox do
|
|||
id={"dropdown-#{@ref}"}
|
||||
x-show="isOpen"
|
||||
x-ref="suggestions"
|
||||
class="text-sm w-full dropdown z-50 absolute mt-1 max-h-60 overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1/5 ring-black focus:outline-hidden dark:bg-gray-900"
|
||||
class="text-sm w-full dropdown z-50 absolute mt-1 max-h-60 overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1/5 ring-black focus:outline-hidden dark:bg-gray-800"
|
||||
style="display: none;"
|
||||
>
|
||||
<.option
|
||||
|
|
@ -242,7 +242,7 @@ defmodule PlausibleWeb.Live.Components.ComboBox do
|
|||
@creatable && "creatable"
|
||||
]}
|
||||
@mouseenter={"setFocus(#{@idx})"}
|
||||
x-bind:class={ "{'text-white bg-indigo-500': focus === #{@idx}}" }
|
||||
x-bind:class={ "{'bg-gray-100 dark:bg-gray-700': focus === #{@idx}}" }
|
||||
id={"dropdown-#{@ref}-option-#{@idx}"}
|
||||
>
|
||||
<a
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
<.input name="my-input" errors={["oh no!"]} />
|
||||
"""
|
||||
|
||||
@default_input_class "text-sm text-gray-900 dark:text-white dark:bg-gray-900 block pl-3.5 py-2.5 border-gray-300 dark:border-gray-700 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 rounded-md"
|
||||
@default_input_class "text-sm text-gray-900 dark:text-white dark:bg-gray-750 block pl-3.5 py-2.5 border-gray-300 dark:border-gray-800 transition-all duration-150 focus:outline-none focus:ring-3 focus:ring-indigo-500/20 dark:focus:ring-indigo-500/25 focus:border-indigo-500 rounded-md disabled:bg-gray-100 disabled:dark:bg-gray-800 disabled:border-gray-200 disabled:dark:border-gray-800 disabled:text-gray-900/40 disabled:dark:text-white/30 disabled:cursor-not-allowed"
|
||||
|
||||
attr(:id, :any, default: nil)
|
||||
attr(:name, :any)
|
||||
|
|
@ -110,7 +110,7 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
checked={@checked}
|
||||
id={@id}
|
||||
name={@name}
|
||||
class="block h-5 w-5 rounded-sm dark:bg-gray-700 border-gray-300 text-indigo-600 focus:ring-indigo-600"
|
||||
class="block size-5 rounded-sm dark:bg-gray-600 border-gray-300 dark:border-gray-600 text-indigo-600"
|
||||
{@rest}
|
||||
/>
|
||||
{@label}
|
||||
|
|
@ -130,7 +130,7 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
id={@id}
|
||||
name={@name}
|
||||
checked={assigns[:checked]}
|
||||
class="block dark:bg-gray-900 h-4 w-4 mt-[0.15rem] cursor-pointer text-indigo-600 border-gray-300 dark:border-gray-500 focus:ring-indigo-500"
|
||||
class="block dark:bg-gray-900 size-4.5 mt-px cursor-pointer text-indigo-600 border-gray-400 dark:border-gray-600 checked:border-indigo-600 dark:checked:border-white"
|
||||
{@rest}
|
||||
/>
|
||||
<.label :if={@label} class="flex flex-col flex-inline" for={@id}>
|
||||
|
|
@ -230,9 +230,9 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
<a
|
||||
onclick={"var input = document.getElementById('#{@id}'); input.focus(); input.select(); document.execCommand('copy'); event.stopPropagation();"}
|
||||
href="javascript:void(0)"
|
||||
class="absolute flex items-center text-xs font-medium text-indigo-600 no-underline hover:underline top-3 right-4"
|
||||
class="absolute flex items-center text-xs font-medium text-indigo-600 dark:text-indigo-500 no-underline hover:text-indigo-700 dark:hover:text-indigo-400 top-3 right-4 transition-colors duration-150"
|
||||
>
|
||||
<Heroicons.document_duplicate class="pr-1 text-indigo-600 dark:text-indigo-500 w-5 h-5" />
|
||||
<Heroicons.document_duplicate class="pr-1 size-5" />
|
||||
<span>
|
||||
COPY
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ defmodule PlausibleWeb.Live.Components.Modal do
|
|||
|
||||
def render(assigns) do
|
||||
class = [
|
||||
"md:w-1/2 w-full max-w-md mx-auto bg-white dark:bg-gray-800 shadow-xl rounded-lg px-8 pt-6 pb-8 top-24",
|
||||
"md:w-1/2 w-full max-w-md mx-auto bg-white dark:bg-gray-900 shadow-xl rounded-lg px-8 pt-6 pb-8 top-24",
|
||||
assigns.class
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ defmodule PlausibleWeb.Live.Components.Verification do
|
|||
<a
|
||||
href="#"
|
||||
@click.prevent="showDiagnostics = !showDiagnostics"
|
||||
class="bg-yellow-100 dark:text-gray-800"
|
||||
class="bg-yellow-100 dark:bg-yellow-800/40"
|
||||
>
|
||||
As a super-admin, you're eligible to see diagnostics details. Click to expand.
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -98,10 +98,10 @@ defmodule PlausibleWeb.Live.CSVImport do
|
|||
~H"""
|
||||
<label
|
||||
phx-drop-target={@upload.ref}
|
||||
class="block border-2 dark:border-gray-600 rounded-md p-4 hover:bg-gray-50 dark:hover:bg-gray-900 hover:border-indigo-500 dark:hover:border-indigo-600 transition cursor-pointer"
|
||||
class="block border border-gray-300 dark:border-gray-750 dark:bg-gray-750 rounded-md p-4 transition cursor-pointer"
|
||||
>
|
||||
<div class="hidden md:flex items-center text-gray-500 dark:text-gray-500">
|
||||
<Heroicons.document_plus class="w-5 h-5 transition" />
|
||||
<div class="hidden md:flex items-center text-gray-500 dark:text-gray-400">
|
||||
<Heroicons.document_plus class="size-5 transition" />
|
||||
<span class="ml-1.5 text-sm">
|
||||
(or drag-and-drop your unzipped CSVs here)
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
def edit_form(assigns) do
|
||||
~H"""
|
||||
<.form :let={f} for={@form} phx-submit="save-goal" phx-target={@myself}>
|
||||
<.title>Edit Goal for {@domain}</.title>
|
||||
<.title>Edit goal for {@domain}</.title>
|
||||
|
||||
<.custom_event_fields
|
||||
:if={@selected_tab == "custom_events"}
|
||||
|
|
@ -96,7 +96,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
/>
|
||||
|
||||
<.button type="submit" class="w-full">
|
||||
Update Goal
|
||||
Update goal
|
||||
</.button>
|
||||
</.form>
|
||||
"""
|
||||
|
|
@ -111,9 +111,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
phx-submit="save-goal"
|
||||
phx-target={@myself}
|
||||
>
|
||||
<.spinner class="spinner block absolute right-9 top-8" x-show="tabSelectionInProgress" />
|
||||
|
||||
<.title>Add Goal for {@domain}</.title>
|
||||
<.title>Add goal for {@domain}</.title>
|
||||
|
||||
<.tabs current_user={@current_user} site={@site} selected_tab={@selected_tab} myself={@myself} />
|
||||
|
||||
|
|
@ -149,7 +147,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
|
||||
<div x-show="!tabSelectionInProgress">
|
||||
<.button type="submit" class="w-full">
|
||||
Add Goal
|
||||
Add goal
|
||||
</.button>
|
||||
</div>
|
||||
|
||||
|
|
@ -190,7 +188,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
</div>
|
||||
|
||||
<.label for={"page_path_input_#{@suffix}"}>
|
||||
Page Path
|
||||
Page path
|
||||
</.label>
|
||||
|
||||
<.live_component
|
||||
|
|
@ -211,7 +209,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
</.error>
|
||||
|
||||
<.input
|
||||
label="Display Name"
|
||||
label="Display name"
|
||||
id="pageview_display_name_input"
|
||||
field={@f[:display_name]}
|
||||
type="text"
|
||||
|
|
@ -268,7 +266,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
</div>
|
||||
|
||||
<.label for={"scroll_threshold_input_#{@suffix}"}>
|
||||
Scroll Percentage Threshold (1-100)
|
||||
Scroll percentage threshold (1-100)
|
||||
</.label>
|
||||
|
||||
<.input
|
||||
|
|
@ -284,7 +282,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
/>
|
||||
|
||||
<.label for={"scroll_page_path_input_#{@suffix}"} class="mt-3">
|
||||
Page Path
|
||||
Page path
|
||||
</.label>
|
||||
|
||||
<.live_component
|
||||
|
|
@ -305,7 +303,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
</.error>
|
||||
|
||||
<.input
|
||||
label="Display Name"
|
||||
label="Display name"
|
||||
id="scroll_display_name_input"
|
||||
field={@f[:display_name]}
|
||||
type="text"
|
||||
|
|
@ -344,7 +342,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
|
||||
<div>
|
||||
<.label for={"event_name_input_#{@suffix}"}>
|
||||
Event Name
|
||||
Event name
|
||||
</.label>
|
||||
|
||||
<.live_component
|
||||
|
|
@ -369,7 +367,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
|
||||
<div class="mt-2">
|
||||
<.input
|
||||
label="Display Name"
|
||||
label="Display name"
|
||||
id="custom_event_display_name_input"
|
||||
field={@f[:display_name]}
|
||||
type="text"
|
||||
|
|
@ -447,69 +445,58 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
|
||||
def tabs(assigns) do
|
||||
~H"""
|
||||
<div class="text-sm mt-6 font-medium dark:text-gray-100">Goal Trigger</div>
|
||||
<div class="my-2 text-sm w-full flex rounded-sm border border-gray-300 dark:border-gray-500 overflow-hidden">
|
||||
<.custom_events_tab selected?={@selected_tab == "custom_events"} myself={@myself} />
|
||||
<.pageviews_tab selected?={@selected_tab == "pageviews"} myself={@myself} />
|
||||
<.scroll_tab selected?={@selected_tab == "scroll"} myself={@myself} />
|
||||
<div class="text-sm mt-6 font-medium dark:text-gray-100">Goal trigger</div>
|
||||
<div class="my-2 text-sm w-full flex gap-1 overflow-hidden">
|
||||
<.tab
|
||||
id="event-tab"
|
||||
tab_value="custom_events"
|
||||
selected?={@selected_tab == "custom_events"}
|
||||
myself={@myself}
|
||||
>
|
||||
Custom event
|
||||
</.tab>
|
||||
<.tab
|
||||
id="pageview-tab"
|
||||
tab_value="pageviews"
|
||||
selected?={@selected_tab == "pageviews"}
|
||||
myself={@myself}
|
||||
>
|
||||
Pageview
|
||||
</.tab>
|
||||
<.tab
|
||||
id="scroll-tab"
|
||||
tab_value="scroll"
|
||||
selected?={@selected_tab == "scroll"}
|
||||
myself={@myself}
|
||||
>
|
||||
Scroll depth
|
||||
</.tab>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp custom_events_tab(assigns) do
|
||||
attr(:id, :string, required: true)
|
||||
attr(:tab_value, :string, required: true)
|
||||
attr(:selected?, :boolean, required: true)
|
||||
attr(:myself, :any, required: true)
|
||||
slot(:inner_block, required: true)
|
||||
|
||||
defp tab(assigns) do
|
||||
~H"""
|
||||
<a
|
||||
class={[
|
||||
"flex-1 text-center py-2.5 border-r dark:border-gray-500",
|
||||
"flex-1 text-center py-2.5 rounded-md font-medium hover:bg-gray-100 dark:hover:bg-gray-750 transition-colors duration-150",
|
||||
"cursor-pointer",
|
||||
@selected? && "shadow-inner font-medium bg-indigo-600 text-white",
|
||||
!@selected? && "dark:text-gray-100 text-gray-800"
|
||||
@selected? && "bg-gray-150 dark:bg-gray-700 text-gray-800 dark:text-white",
|
||||
!@selected? && "dark:text-gray-200 text-gray-600 hover:text-gray-800 dark:hover:text-white"
|
||||
]}
|
||||
id="event-tab"
|
||||
id={@id}
|
||||
x-on:click={!@selected? && "tabSelectionInProgress = true"}
|
||||
phx-click="switch-tab"
|
||||
phx-value-tab="custom_events"
|
||||
phx-value-tab={@tab_value}
|
||||
phx-target={@myself}
|
||||
>
|
||||
Custom Event
|
||||
</a>
|
||||
"""
|
||||
end
|
||||
|
||||
def pageviews_tab(assigns) do
|
||||
~H"""
|
||||
<a
|
||||
class={[
|
||||
"flex-1 text-center py-2.5 cursor-pointer",
|
||||
@selected? && "shadow-inner font-medium bg-indigo-600 text-white",
|
||||
!@selected? && "dark:text-gray-100 text-gray-800"
|
||||
]}
|
||||
id="pageview-tab"
|
||||
x-on:click={!@selected? && "tabSelectionInProgress = true"}
|
||||
phx-click="switch-tab"
|
||||
phx-value-tab="pageviews"
|
||||
phx-target={@myself}
|
||||
>
|
||||
Pageview
|
||||
</a>
|
||||
"""
|
||||
end
|
||||
|
||||
def scroll_tab(assigns) do
|
||||
~H"""
|
||||
<a
|
||||
class={[
|
||||
"flex-1 text-center py-2.5 cursor-pointer border-l dark:border-gray-500",
|
||||
@selected? && "shadow-inner font-medium bg-indigo-600 text-white",
|
||||
!@selected? && "dark:text-gray-100 text-gray-800"
|
||||
]}
|
||||
id="scroll-tab"
|
||||
x-on:click={!@selected? && "tabSelectionInProgress = true"}
|
||||
phx-click="switch-tab"
|
||||
phx-value-tab="scroll"
|
||||
phx-target={@myself}
|
||||
>
|
||||
Scroll Depth
|
||||
{render_slot(@inner_block)}
|
||||
</a>
|
||||
"""
|
||||
end
|
||||
|
|
@ -628,7 +615,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
else: "text-gray-500 dark:text-gray-400"
|
||||
)
|
||||
]}>
|
||||
Enable Revenue Tracking
|
||||
Enable revenue tracking
|
||||
</span>
|
||||
</div>
|
||||
</.tooltip>
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ defmodule PlausibleWeb.Live.GoalSettings.List do
|
|||
x-data
|
||||
x-on:click={Modal.JS.preopen("goals-form-modal")}
|
||||
>
|
||||
Add Goal
|
||||
Add goal
|
||||
</.button>
|
||||
</.filter_bar>
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ defmodule PlausibleWeb.Live.GoalSettings.List do
|
|||
<span :if={goal.page_path && goal.scroll_threshold == -1}>Pageview</span>
|
||||
<span :if={goal.event_name && !goal.currency}>Custom Event</span>
|
||||
<span :if={goal.currency}>Revenue Goal ({goal.currency})</span>
|
||||
<span :if={not Enum.empty?(goal.funnels)} class="text-gray-400 dark:text-gray-600">
|
||||
<span :if={not Enum.empty?(goal.funnels)} class="text-gray-400 dark:text-gray-500">
|
||||
<br />Belongs to funnel(s)
|
||||
</span>
|
||||
</.td>
|
||||
|
|
@ -127,19 +127,19 @@ defmodule PlausibleWeb.Live.GoalSettings.List do
|
|||
~H"""
|
||||
<span
|
||||
:if={@goal.page_path && @goal.scroll_threshold > -1}
|
||||
class="block truncate text-gray-400 dark:text-gray-600"
|
||||
class="block truncate text-gray-400 dark:text-gray-500"
|
||||
>
|
||||
{page_scroll_description(@goal)}
|
||||
</span>
|
||||
|
||||
<span
|
||||
:if={@goal.page_path && @goal.scroll_threshold == -1}
|
||||
class="block truncate text-gray-400 dark:text-gray-600"
|
||||
class="block truncate text-gray-400 dark:text-gray-500"
|
||||
>
|
||||
{pageview_description(@goal)}
|
||||
</span>
|
||||
|
||||
<span :if={@goal.event_name} class="block truncate text-gray-400 dark:text-gray-600">
|
||||
<span :if={@goal.event_name} class="block truncate text-gray-400 dark:text-gray-500">
|
||||
{custom_event_description(@goal)}
|
||||
</span>
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ defmodule PlausibleWeb.Live.ImportsExportsSettings do
|
|||
|
||||
<div class="flex gap-x-4">
|
||||
<.button_link
|
||||
theme="bright"
|
||||
theme="secondary"
|
||||
href={Plausible.Google.API.import_authorize_url(@site.id)}
|
||||
disabled={@import_in_progress? or @at_maximum?}
|
||||
mt?={false}
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ defmodule PlausibleWeb.Live.Installation do
|
|||
</div>
|
||||
</:loading>
|
||||
|
||||
<div class="grid grid-cols-2 sm:flex sm:flex-row gap-2 bg-gray-100 dark:bg-gray-900 rounded-md p-1">
|
||||
<div class="grid grid-cols-2 sm:flex sm:flex-row gap-1 rounded-md">
|
||||
<.tab
|
||||
patch={"?type=manual&flow=#{@flow}"}
|
||||
selected={@installation_type.result == "manual"}
|
||||
|
|
@ -271,19 +271,18 @@ defmodule PlausibleWeb.Live.Installation do
|
|||
slot :inner_block, required: true
|
||||
|
||||
defp tab(assigns) do
|
||||
assigns =
|
||||
base_classes =
|
||||
"rounded-md px-3.5 py-2.5 text-sm font-medium flex items-center flex-1 justify-center whitespace-nowrap hover:bg-gray-100 dark:hover:bg-gray-750 transition-colors duration-150"
|
||||
|
||||
selected_class =
|
||||
if assigns[:selected] do
|
||||
assign(assigns,
|
||||
class:
|
||||
"bg-white dark:bg-gray-800 rounded-md px-3.5 py-2.5 text-sm font-medium flex items-center flex-1 justify-center whitespace-nowrap"
|
||||
)
|
||||
"bg-gray-150 dark:bg-gray-700"
|
||||
else
|
||||
assign(assigns,
|
||||
class:
|
||||
"bg-gray-100 dark:bg-gray-700 rounded-md px-3.5 py-2.5 text-sm font-medium flex items-center cursor-pointer flex-1 justify-center whitespace-nowrap"
|
||||
)
|
||||
"bg-transparent cursor-pointer"
|
||||
end
|
||||
|
||||
assigns = assign(assigns, class: "#{selected_class} #{base_classes}")
|
||||
|
||||
~H"""
|
||||
<.link patch={@patch} class={@class}>
|
||||
{render_slot(@inner_block)}
|
||||
|
|
|
|||
|
|
@ -193,16 +193,16 @@ defmodule PlausibleWeb.Live.Installation.Instructions do
|
|||
<.tooltip sticky?={false}>
|
||||
<:tooltip_content>
|
||||
{@tooltip}
|
||||
<br /><br />Click to learn more.
|
||||
<br />Click to learn more.
|
||||
</:tooltip_content>
|
||||
<a href={@learn_more} target="_blank" rel="noopener noreferrer">
|
||||
<Heroicons.information_circle class="text-indigo-700 dark:text-gray-500 w-5 h-5 hover:stroke-2" />
|
||||
<Heroicons.information_circle class="inline-block text-indigo-700 dark:text-gray-500 size-5 hover:stroke-2" />
|
||||
</a>
|
||||
</.tooltip>
|
||||
</div>
|
||||
<div class="ml-2 visible md:invisible">
|
||||
<a href={@learn_more} target="_blank" rel="noopener noreferrer">
|
||||
<Heroicons.information_circle class="text-indigo-700 dark:text-gray-500 w-5 h-5 hover:stroke-2" />
|
||||
<Heroicons.information_circle class="inline-block text-indigo-700 dark:text-gray-500 size-5 hover:stroke-2" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -219,16 +219,16 @@ defmodule PlausibleWeb.Live.Installation.Instructions do
|
|||
<.tooltip sticky?={false}>
|
||||
<:tooltip_content>
|
||||
{@tooltip}
|
||||
<br /><br />Click to learn more.
|
||||
<br />Click to learn more.
|
||||
</:tooltip_content>
|
||||
<a href={@learn_more} target="_blank" rel="noopener noreferrer">
|
||||
<Heroicons.information_circle class="text-indigo-700 dark:text-gray-500 w-5 h-5 hover:stroke-2" />
|
||||
<Heroicons.information_circle class="inline-block text-indigo-700 dark:text-gray-500 size-5 hover:stroke-2" />
|
||||
</a>
|
||||
</.tooltip>
|
||||
</div>
|
||||
<div class="ml-2 visible md:invisible">
|
||||
<a href={@learn_more} target="_blank" rel="noopener noreferrer">
|
||||
<Heroicons.information_circle class="text-indigo-700 dark:text-gray-500 w-5 h-5 hover:stroke-2" />
|
||||
<Heroicons.information_circle class="inline-block text-indigo-700 dark:text-gray-500 size-5 hover:stroke-2" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -241,7 +241,7 @@ defmodule PlausibleWeb.Live.Installation.Instructions do
|
|||
<div class="relative">
|
||||
<textarea
|
||||
id="snippet"
|
||||
class={"w-full border-1 border-gray-300 rounded-md p-4 text-sm text-gray-700 dark:border-gray-500 dark:bg-gray-900 dark:text-gray-300 #{if !@resizable, do: "resize-none"}"}
|
||||
class={"w-full border-1 border-gray-300 rounded-md p-4 text-sm text-gray-700 dark:border-gray-750 dark:bg-gray-750 dark:text-gray-300 #{if !@resizable, do: "resize-none"}"}
|
||||
rows={@rows}
|
||||
readonly
|
||||
><%= @text %></textarea>
|
||||
|
|
@ -249,9 +249,9 @@ defmodule PlausibleWeb.Live.Installation.Instructions do
|
|||
<a
|
||||
onclick="var input = document.getElementById('snippet'); input.focus(); input.select(); document.execCommand('copy'); event.stopPropagation();"
|
||||
href="javascript:void(0)"
|
||||
class="absolute flex items-center text-xs font-medium text-indigo-600 no-underline hover:underline bottom-2 right-4 p-2 bg-white dark:bg-gray-900"
|
||||
class="absolute flex items-center text-xs font-medium text-indigo-600 no-underline bottom-2 right-4 p-2 bg-white transition-colors duration-150 hover:text-indigo-700 dark:text-indigo-500 dark:hover:text-indigo-400 dark:bg-gray-750"
|
||||
>
|
||||
<Heroicons.document_duplicate class="pr-1 text-indigo-600 dark:text-indigo-500 w-5 h-5" />
|
||||
<Heroicons.document_duplicate class="pr-1 text-current size-5" />
|
||||
<span>
|
||||
COPY
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ defmodule PlausibleWeb.Live.Plugins.API.TokenForm do
|
|||
<div class="fixed inset-0 flex items-center justify-center mt-16 z-50 overflow-y-auto overflow-x-hidden">
|
||||
<div class="w-1/2 h-full">
|
||||
<div
|
||||
class="max-w-md w-full mx-auto bg-white dark:bg-gray-800 shadow-md rounded-sm px-8 pt-6 pb-8 mb-4 mt-8"
|
||||
class="max-w-md w-full mx-auto bg-white dark:bg-gray-900 shadow-md rounded-sm px-8 pt-6 pb-8 mb-4 mt-8"
|
||||
phx-click-away="close-token-modal"
|
||||
>
|
||||
<%= if @token_generated do %>
|
||||
|
|
@ -67,21 +67,22 @@ defmodule PlausibleWeb.Live.Plugins.API.TokenForm do
|
|||
/>
|
||||
</div>
|
||||
<p class="mt-4 text-sm text-gray-500 dark:text-gray-400">
|
||||
Please copy the token and store it in a secure place as it won't be shown again.
|
||||
Copy the token and store it in a secure place, as it won't be shown again.
|
||||
<span :if={@token_description == "WordPress"}>
|
||||
You'll need to paste the token in the settings area of the Plausible WordPress plugin.
|
||||
</span>
|
||||
</p>
|
||||
<.button
|
||||
theme="secondary"
|
||||
phx-click="close-token-modal"
|
||||
class="w-full border !border-gray-300 dark:!border-gray-500 !text-gray-700 dark:!text-gray-300 !bg-transparent hover:!bg-gray-100 dark:hover:!bg-gray-850"
|
||||
class="w-full"
|
||||
>
|
||||
Close modal
|
||||
</.button>
|
||||
<% else %>
|
||||
<.form :let={f} for={@form} phx-submit="generate-token">
|
||||
<.title>
|
||||
Create Plugin Token for {@domain}
|
||||
Create plugin token for {@domain}
|
||||
</.title>
|
||||
|
||||
<div class="mt-4">
|
||||
|
|
@ -100,7 +101,7 @@ defmodule PlausibleWeb.Live.Plugins.API.TokenForm do
|
|||
Once created, we will display the token so it can be copied.
|
||||
</p>
|
||||
<.button type="submit" class="w-full">
|
||||
Create Plugin Token
|
||||
Create plugin token
|
||||
</.button>
|
||||
</.form>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@ defmodule PlausibleWeb.Live.PropsSettings.Form do
|
|||
<.form
|
||||
:let={f}
|
||||
for={@form}
|
||||
class="max-w-md w-full mx-auto bg-white dark:bg-gray-800 shadow-md rounded-sm px-8 pt-6 pb-8 mb-4 mt-8"
|
||||
class="max-w-md w-full mx-auto bg-white dark:bg-gray-900 shadow-md rounded-sm px-8 pt-6 pb-8 mb-4 mt-8"
|
||||
phx-submit="allow-prop"
|
||||
phx-click-away="cancel-allow-prop"
|
||||
>
|
||||
<.title>Add Property for {@domain}</.title>
|
||||
<.title>Add property for {@domain}</.title>
|
||||
|
||||
<div class="mt-6">
|
||||
<.label for="prop_input">
|
||||
|
|
@ -99,7 +99,7 @@ defmodule PlausibleWeb.Live.PropsSettings.Form do
|
|||
</div>
|
||||
|
||||
<.button type="submit" class="w-full">
|
||||
Add Property →
|
||||
Add property
|
||||
</.button>
|
||||
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ defmodule PlausibleWeb.Live.PropsSettings.List do
|
|||
<div>
|
||||
<.filter_bar filter_text={@filter_text} placeholder="Search Properties">
|
||||
<.button phx-click="add-prop" mt?={false}>
|
||||
Add Property
|
||||
Add property
|
||||
</.button>
|
||||
</.filter_bar>
|
||||
<%= if is_list(@props) && length(@props) > 0 do %>
|
||||
|
|
|
|||
|
|
@ -106,9 +106,9 @@ defmodule PlausibleWeb.Live.Shields.CountryRules do
|
|||
for={@form}
|
||||
phx-submit="save-country-rule"
|
||||
phx-target={@myself}
|
||||
class="max-w-md w-full mx-auto bg-white dark:bg-gray-800"
|
||||
class="max-w-md w-full mx-auto"
|
||||
>
|
||||
<.title>Add Country to Block List</.title>
|
||||
<.title>Add country to block list</.title>
|
||||
|
||||
<.live_component
|
||||
class="mt-4"
|
||||
|
|
@ -126,7 +126,7 @@ defmodule PlausibleWeb.Live.Shields.CountryRules do
|
|||
Once added, we will start rejecting traffic from this country within a few minutes.
|
||||
</p>
|
||||
<.button type="submit" class="w-full">
|
||||
Add Country
|
||||
Add country
|
||||
</.button>
|
||||
</.form>
|
||||
</.live_component>
|
||||
|
|
|
|||
|
|
@ -120,9 +120,9 @@ defmodule PlausibleWeb.Live.Shields.HostnameRules do
|
|||
for={@form}
|
||||
phx-submit="save-hostname-rule"
|
||||
phx-target={@myself}
|
||||
class="max-w-md w-full mx-auto bg-white dark:bg-gray-800"
|
||||
class="max-w-md w-full mx-auto"
|
||||
>
|
||||
<.title>Add Hostname to Allow List</.title>
|
||||
<.title>Add hostname to allow list</.title>
|
||||
|
||||
<.live_component
|
||||
class="mt-8"
|
||||
|
|
@ -148,7 +148,7 @@ defmodule PlausibleWeb.Live.Shields.HostnameRules do
|
|||
<% end %>
|
||||
</p>
|
||||
<.button type="submit" class="w-full">
|
||||
Add Hostname
|
||||
Add hostname
|
||||
</.button>
|
||||
</.form>
|
||||
</.live_component>
|
||||
|
|
|
|||
|
|
@ -121,9 +121,9 @@ defmodule PlausibleWeb.Live.Shields.IPRules do
|
|||
for={@form}
|
||||
phx-submit="save-ip-rule"
|
||||
phx-target={@myself}
|
||||
class="max-w-md w-full mx-auto bg-white dark:bg-gray-800"
|
||||
class="max-w-md w-full mx-auto"
|
||||
>
|
||||
<.title>Add IP to Block List</.title>
|
||||
<.title>Add IP to block list</.title>
|
||||
|
||||
<div class="mt-4">
|
||||
<p
|
||||
|
|
@ -140,7 +140,7 @@ defmodule PlausibleWeb.Live.Shields.IPRules do
|
|||
<.input
|
||||
autofocus
|
||||
field={f[:inet]}
|
||||
label="IP Address"
|
||||
label="IP address"
|
||||
placeholder="e.g. 192.168.127.12"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -155,7 +155,7 @@ defmodule PlausibleWeb.Live.Shields.IPRules do
|
|||
Once added, we will start rejecting traffic from this IP within a few minutes.
|
||||
</p>
|
||||
<.button type="submit" class="w-full">
|
||||
Add IP Address →
|
||||
Add IP address
|
||||
</.button>
|
||||
</.form>
|
||||
</.live_component>
|
||||
|
|
|
|||
|
|
@ -115,9 +115,9 @@ defmodule PlausibleWeb.Live.Shields.PageRules do
|
|||
for={@form}
|
||||
phx-submit="save-page-rule"
|
||||
phx-target={@myself}
|
||||
class="max-w-md w-full mx-auto bg-white dark:bg-gray-800"
|
||||
class="max-w-md w-full mx-auto"
|
||||
>
|
||||
<.title>Add Page to Block List</.title>
|
||||
<.title>Add page to block list</.title>
|
||||
|
||||
<.live_component
|
||||
class="mt-4"
|
||||
|
|
@ -141,7 +141,7 @@ defmodule PlausibleWeb.Live.Shields.PageRules do
|
|||
Once added, we will start rejecting traffic from this page within a few minutes.
|
||||
</p>
|
||||
<.button type="submit" class="w-full">
|
||||
Add Page
|
||||
Add page
|
||||
</.button>
|
||||
</.form>
|
||||
</.live_component>
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
@needs_to_upgrade == {:needs_to_upgrade, :no_active_trial_or_subscription}
|
||||
} />
|
||||
|
||||
<div class="group mt-6 pb-5 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
|
||||
<div class="group mt-6 pb-5 border-b border-gray-200 dark:border-gray-750 flex items-center justify-between">
|
||||
<h2 class="text-2xl font-bold leading-7 text-gray-900 dark:text-gray-100 sm:text-3xl sm:leading-9 sm:truncate shrink-0">
|
||||
{Teams.name(@current_team)}
|
||||
<.unstyled_link
|
||||
|
|
@ -154,11 +154,11 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
|
||||
def upgrade_nag_screen(assigns) do
|
||||
~H"""
|
||||
<div class="rounded-md bg-yellow-100 p-4">
|
||||
<div class="rounded-md bg-yellow-100 dark:bg-yellow-900/40 p-5">
|
||||
<div class="flex">
|
||||
<div class="shrink-0">
|
||||
<svg
|
||||
class="h-5 w-5 text-yellow-400"
|
||||
class="size-5 mt-0.5 text-yellow-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
|
|
@ -171,11 +171,11 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<h3 class="text-sm font-medium text-yellow-800">
|
||||
<div class="ml-2">
|
||||
<h3 class="font-medium text-gray-900 dark:text-gray-100">
|
||||
Payment required
|
||||
</h3>
|
||||
<div class="mt-2 text-sm text-yellow-700">
|
||||
<div class="mt-1 text-sm text-gray-900/80 dark:text-gray-100/60">
|
||||
<p>
|
||||
To access the sites you own, you need to subscribe to a monthly or yearly payment plan.
|
||||
<.styled_link href={Routes.settings_path(PlausibleWeb.Endpoint, :subscription)}>
|
||||
|
|
@ -220,7 +220,7 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
~H"""
|
||||
<li
|
||||
data-test-id="consolidated-view-card"
|
||||
class="relative row-span-2 bg-white p-6 dark:bg-gray-800 rounded-md shadow-sm cursor-pointer hover:shadow-lg transition-shadow duration-150"
|
||||
class="relative row-span-2 bg-white p-6 dark:bg-gray-900 rounded-md shadow-sm cursor-pointer hover:shadow-lg transition-shadow duration-150"
|
||||
>
|
||||
<.unstyled_link
|
||||
href={"/#{URI.encode_www_form(@consolidated_view.domain)}"}
|
||||
|
|
@ -281,10 +281,10 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
class="flex flex-col gap-y-2 min-h-[254px] h-full text-center animate-pulse"
|
||||
data-test-id="consolidated-viw-stats-loading"
|
||||
>
|
||||
<div class="flex-2 dark:bg-gray-700 bg-gray-100 rounded-md"></div>
|
||||
<div class="flex-2 dark:bg-gray-750 bg-gray-100 rounded-md"></div>
|
||||
<div class="flex-1 flex flex-col gap-y-2">
|
||||
<div class="w-full h-full dark:bg-gray-700 bg-gray-100 rounded-md"></div>
|
||||
<div class="w-full h-full dark:bg-gray-700 bg-gray-100 rounded-md"></div>
|
||||
<div class="w-full h-full dark:bg-gray-750 bg-gray-100 rounded-md"></div>
|
||||
<div class="w-full h-full dark:bg-gray-750 bg-gray-100 rounded-md"></div>
|
||||
</div>
|
||||
</div>
|
||||
</.unstyled_link>
|
||||
|
|
@ -328,7 +328,7 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
data-domain={@site.domain}
|
||||
x-on:click={"invitationOpen = true; selectedInvitation = invitations['#{@invitation.invitation_id}']"}
|
||||
>
|
||||
<div class="col-span-1 flex flex-col gap-y-5 bg-white dark:bg-gray-800 rounded-md shadow-sm p-6 group-hover:shadow-lg cursor-pointer transition duration-100">
|
||||
<div class="col-span-1 flex flex-col gap-y-5 bg-white dark:bg-gray-900 rounded-md shadow-sm p-6 group-hover:shadow-lg cursor-pointer transition duration-100">
|
||||
<div class="w-full flex items-center justify-between gap-x-2.5">
|
||||
<.favicon domain={@site.domain} />
|
||||
<div class="flex-1 w-full truncate">
|
||||
|
|
@ -369,7 +369,7 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
}
|
||||
>
|
||||
<.unstyled_link href={"/#{URI.encode_www_form(@site.domain)}"}>
|
||||
<div class="col-span-1 flex flex-col gap-y-5 bg-white dark:bg-gray-800 rounded-md shadow-sm p-6 group-hover:shadow-lg cursor-pointer transition duration-100">
|
||||
<div class="col-span-1 flex flex-col gap-y-5 bg-white dark:bg-gray-900 rounded-md shadow-sm p-6 group-hover:shadow-lg cursor-pointer transition duration-100">
|
||||
<div class="w-full flex items-center justify-between gap-x-2.5">
|
||||
<.favicon domain={@site.domain} />
|
||||
<div class="flex-1 w-full">
|
||||
|
|
@ -479,8 +479,8 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
"flex flex-col gap-y-2 h-[122px] text-center animate-pulse",
|
||||
is_map(@hourly_stats) && " hidden"
|
||||
]}>
|
||||
<div class="flex-2 dark:bg-gray-700 bg-gray-100 rounded-md"></div>
|
||||
<div class="flex-1 dark:bg-gray-700 bg-gray-100 rounded-md"></div>
|
||||
<div class="flex-2 dark:bg-gray-750 bg-gray-100 rounded-md"></div>
|
||||
<div class="flex-1 dark:bg-gray-750 bg-gray-100 rounded-md"></div>
|
||||
</div>
|
||||
<div :if={is_map(@hourly_stats)}>
|
||||
<span class="flex flex-col gap-y-5 text-gray-600 dark:text-gray-400 text-sm truncate">
|
||||
|
|
@ -687,7 +687,7 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
</.button_link>
|
||||
<.button_link
|
||||
href="#"
|
||||
theme="bright"
|
||||
theme="secondary"
|
||||
data-method="post"
|
||||
data-csrf={Plug.CSRFProtection.get_csrf_token()}
|
||||
x-bind:data-to="selectedInvitation && ('/sites/invitations/' + selectedInvitation.invitation.invitation_id + '/reject')"
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ defmodule PlausibleWeb.Live.TeamManagement do
|
|||
</div>
|
||||
|
||||
<.dropdown id="input-role-picker">
|
||||
<:button class="role border rounded-sm border-indigo-700 bg-transparent text-gray-800 dark:text-gray-100 hover:bg-gray-50 dark:hover:bg-gray-700 focus-visible:outline-gray-100 whitespace-nowrap truncate inline-flex items-center gap-x-2 font-medium rounded-md px-3 py-2 text-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:bg-gray-400 dark:disabled:text-white dark:disabled:text-gray-400 dark:disabled:bg-gray-700">
|
||||
<:button class="role inline-flex items-center gap-x-2 font-medium rounded-md px-3 py-2 text-sm border border-gray-300 dark:border-gray-750 rounded-md text-gray-800 dark:text-gray-100 dark:bg-gray-750 dark:hover:bg-gray-700 focus-visible:outline-gray-100 whitespace-nowrap truncate shadow-xs hover:shadow-sm transition-all duration-150 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:bg-gray-400 dark:disabled:text-white dark:disabled:text-gray-400 dark:disabled:bg-gray-700">
|
||||
{@input_role |> Atom.to_string() |> String.capitalize()}
|
||||
<Heroicons.chevron_down mini class="size-4 mt-0.5" />
|
||||
</:button>
|
||||
|
|
@ -132,11 +132,11 @@ defmodule PlausibleWeb.Live.TeamManagement do
|
|||
</div>
|
||||
|
||||
<div :if={Layout.has_guests?(@layout)} class="flex items-center mt-4 mb-4" id="guests-hr">
|
||||
<hr class="grow border-t border-gray-200 dark:border-gray-600" />
|
||||
<hr class="grow border-t border-gray-200 dark:border-gray-700" />
|
||||
<span class="mx-4 text-gray-500 text-sm">
|
||||
Guests
|
||||
</span>
|
||||
<hr class="grow border-t border-gray-200 dark:border-gray-600" />
|
||||
<hr class="grow border-t border-gray-200 dark:border-gray-700" />
|
||||
</div>
|
||||
|
||||
<div :if={Layout.has_guests?(@layout)} id="guest-list">
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
>
|
||||
Log in
|
||||
</.button_link>
|
||||
<.button_link theme="bright" href={PlausibleWeb.LayoutView.home_dest(@conn)}>
|
||||
<.button_link theme="secondary" href={PlausibleWeb.LayoutView.home_dest(@conn)}>
|
||||
Go to homepage
|
||||
</.button_link>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<.form
|
||||
:let={f}
|
||||
for={@conn}
|
||||
class="max-w-md w-full mx-auto bg-white dark:bg-gray-800 shadow-md rounded-sm px-8 pt-6 pb-8 mb-4 mt-8"
|
||||
class="max-w-md w-full mx-auto bg-white dark:bg-gray-900 shadow-md rounded-sm px-8 pt-6 pb-8 mb-4 mt-8"
|
||||
onsubmit="confirmButton.disabled = true; return true;"
|
||||
action={Routes.google_analytics_path(@conn, :import, @site.domain)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="mt-24 bg-gray-800 dark:bg-gray-800">
|
||||
<div class="mt-24 bg-gray-800 dark:bg-gray-900">
|
||||
<div class="container px-4 py-12 sm:px-6 lg:py-16 lg:px-8">
|
||||
<div class="xl:grid xl:grid-cols-3 xl:gap-8">
|
||||
<div class="my-8 xl:my-0">
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
logo_path("logo_dark.svg")
|
||||
)
|
||||
}
|
||||
class="inline-block w-40 mr-1"
|
||||
class="inline-block w-32 mr-1"
|
||||
alt="Plausible logo"
|
||||
loading="lazy"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
<div class="absolute inset-y-0 right-0 flex items-center justify-end">
|
||||
<%= cond do %>
|
||||
<% @conn.assigns[:current_user] -> %>
|
||||
<ul class="flex items-center w-full sm:w-auto">
|
||||
<ul class="flex items-center gap-2 w-full sm:w-auto">
|
||||
<li :if={
|
||||
ee?() && @conn.assigns[:site] &&
|
||||
Plausible.Auth.is_super_admin?(@conn.assigns[:current_user])
|
||||
|
|
@ -45,10 +45,10 @@
|
|||
</li>
|
||||
<li
|
||||
:if={ee?() and Plausible.Teams.on_trial?(@conn.assigns[:current_team])}
|
||||
class="hidden mr-6 sm:block"
|
||||
class="hidden sm:block"
|
||||
>
|
||||
<.styled_link
|
||||
class="text-sm text-yellow-900 dark:text-yellow-900 rounded-sm px-3 py-2 rounded-md bg-yellow-100 dark:bg-yellow-100"
|
||||
class="flex items-center h-[40px] px-3 py-2 text-sm text-yellow-700 hover:text-yellow-800 dark:text-yellow-500 dark:hover:text-yellow-500 font-medium rounded-md bg-yellow-100 dark:bg-yellow-800/40 dark:hover:bg-yellow-800/50 transition-colors duration-150"
|
||||
href={Routes.settings_path(@conn, :subscription)}
|
||||
>
|
||||
{trial_notification(@conn.assigns[:current_team])}
|
||||
|
|
@ -56,13 +56,13 @@
|
|||
</li>
|
||||
<li class="w-full sm:w-auto">
|
||||
<.dropdown>
|
||||
<:button class="flex items-center gap-3 px-3 py-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-800">
|
||||
<span class="font-medium truncate dark:text-gray-100 hidden md:block">
|
||||
<:button class="flex items-center gap-2 pl-3 pr-1.5 py-2 rounded-md transition-colors duration-150 hover:bg-gray-100 dark:hover:bg-gray-800">
|
||||
<span class="hidden md:block text-sm font-medium truncate dark:text-gray-100">
|
||||
{@conn.assigns[:current_user].name}
|
||||
</span>
|
||||
<img
|
||||
src={Plausible.Auth.User.profile_img_url(@conn.assigns[:current_user])}
|
||||
class="w-7 rounded-full"
|
||||
class="-my-0.5 w-7 rounded-full"
|
||||
/>
|
||||
</:button>
|
||||
<:menu>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
</head>
|
||||
<body
|
||||
class={[
|
||||
"flex flex-col bg-gray-50 dark:bg-gray-850",
|
||||
"flex flex-col bg-gray-50 dark:bg-gray-950",
|
||||
if !assigns[:embedded] do
|
||||
"h-full"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<.styled_link class="font-semibold text-sm" href="/sites">
|
||||
← Back to sites
|
||||
</.styled_link>
|
||||
<div class="pb-5 border-b border-gray-200 dark:border-gray-700">
|
||||
<div class="pb-5 border-b border-gray-200 dark:border-gray-750">
|
||||
<h2 class="text-2xl font-bold leading-7 text-gray-900 dark:text-gray-100 sm:text-3xl sm:leading-9 sm:truncate">
|
||||
Settings
|
||||
</h2>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
>
|
||||
← Back to stats
|
||||
</.styled_link>
|
||||
<div class="pb-5 border-b border-gray-200 dark:border-gray-700">
|
||||
<div class="pb-5 border-b border-gray-200 dark:border-gray-750">
|
||||
<h2 class="text-2xl font-bold leading-7 text-gray-900 dark:text-gray-100 sm:text-3xl sm:leading-9 sm:truncate">
|
||||
Settings for {@site.domain}
|
||||
</h2>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,12 @@
|
|||
</:tbody>
|
||||
<tr :if={length(invoice_list) > 12}>
|
||||
<td colspan="3" class="text-center pt-8 pb-4">
|
||||
<.button_link href={} theme="bright" x-on:click="showAll = true" x-show="!showAll">
|
||||
<.button_link
|
||||
href={}
|
||||
theme="secondary"
|
||||
x-on:click="showAll = true"
|
||||
x-show="!showAll"
|
||||
>
|
||||
Show more
|
||||
</.button_link>
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
team={@current_team}
|
||||
subscription={@subscription}
|
||||
/>
|
||||
<div class="w-full flex-1 h-32 px-2 py-4 text-center bg-gray-100 rounded-sm dark:bg-gray-900">
|
||||
<div class="w-full flex-1 h-32 px-2 py-4 text-center bg-gray-100 rounded-sm dark:bg-gray-800">
|
||||
<h4 class="font-black dark:text-gray-100">Next bill amount</h4>
|
||||
<%= if Plausible.Billing.Subscription.Status.in?(@subscription, [Plausible.Billing.Subscription.Status.active(), Plausible.Billing.Subscription.Status.past_due()]) do %>
|
||||
<div class="py-2 text-xl font-medium dark:text-gray-100">
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
<div class="py-2 text-xl font-medium dark:text-gray-100">---</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="w-full flex-1 h-32 px-2 py-4 text-center bg-gray-100 rounded-sm dark:bg-gray-900">
|
||||
<div class="w-full flex-1 h-32 px-2 py-4 text-center bg-gray-100 rounded-sm dark:bg-gray-800">
|
||||
<h4 class="font-black dark:text-gray-100">Next bill date</h4>
|
||||
|
||||
<%= if @subscription && @subscription.next_bill_date && Plausible.Billing.Subscription.Status.in?(@subscription, [Plausible.Billing.Subscription.Status.active(), Plausible.Billing.Subscription.Status.past_due()]) do %>
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
</:title>
|
||||
|
||||
<:subtitle>
|
||||
Enter the email address and role of the person you want to invite. We will contact them over email to offer them access to {@site.domain} analytics.<br /><br />
|
||||
The invitation will expire in 48 hours
|
||||
Enter their email and role, and we'll email them an invite to join
|
||||
<span class="font-bold">{@site.domain}</span>
|
||||
analytics. Invitations expire after 48 hours.
|
||||
</:subtitle>
|
||||
|
||||
<.form :let={f} for={@conn} action={Routes.membership_path(@conn, :invite_member, @site.domain)}>
|
||||
|
|
@ -31,13 +32,13 @@
|
|||
<% end %>
|
||||
</div>
|
||||
|
||||
<fieldset x-data="{selectedOption: null}">
|
||||
<fieldset x-data="{selectedOption: null}" class="flex flex-col gap-y-4">
|
||||
<.label for={f[:role].id}>
|
||||
Role
|
||||
</.label>
|
||||
<div class="mt-1 bg-white rounded-md -space-y-px dark:bg-gray-800">
|
||||
<div class="flex flex-col gap-y-4">
|
||||
<label
|
||||
class="border-gray-200 dark:border-gray-500 rounded-tl-md rounded-tr-md relative border p-4 flex cursor-pointer"
|
||||
class="relative flex cursor-pointer"
|
||||
x-class="{'bg-indigo-50 border-indigo-200 dark:bg-indigo-500 dark:border-indigo-800 z-10': selectedOption === 'editor', 'border-gray-200': selectedOption !== 'editor'}"
|
||||
>
|
||||
<.input
|
||||
|
|
@ -67,7 +68,7 @@
|
|||
</label>
|
||||
|
||||
<label
|
||||
class="border-gray-200 dark:border-gray-500 rounded-bl-md rounded-br-md relative border p-4 flex cursor-pointer"
|
||||
class="relative flex cursor-pointer"
|
||||
x-class="{'bg-indigo-50 border-indigo-200 dark:bg-indigo-500 dark:border-indigo-800 z-10': selectedOption === 'viewer', 'border-gray-200': selectedOption !== 'viewer'}"
|
||||
>
|
||||
<.input
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
id="tz-select"
|
||||
value="Etc/Greenwich"
|
||||
disabled={@site_limit_exceeded?}
|
||||
label="Reporting Timezone"
|
||||
label="Reporting timezone"
|
||||
options={Plausible.Timezones.options()}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<.focus_box>
|
||||
<:title>New Shared Link</:title>
|
||||
<:title>New shared link</:title>
|
||||
<:subtitle>
|
||||
Password protection is optional. Please make sure you save it in a secure place. Once the link is created, we cannot reveal the password.
|
||||
</:subtitle>
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@
|
|||
|
||||
<:tbody :let={recipient}>
|
||||
<.td>
|
||||
<div class="flex items-cetner gap-x-2">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<Heroicons.envelope_open class="w-6 h-6 feather" />
|
||||
<div>
|
||||
{recipient}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
<.form :let={f} for={@changeset} action={"/#{URI.encode_www_form(@site.domain)}/settings"}>
|
||||
<.input
|
||||
field={f[:timezone]}
|
||||
label="Reporting Timezone"
|
||||
label="Reporting timezone"
|
||||
type="select"
|
||||
options={Plausible.Timezones.options()}
|
||||
width="w-1/2"
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@
|
|||
<.button type="submit">Save</.button>
|
||||
</.form>
|
||||
<% {:error, error} -> %>
|
||||
<.notice title="Integration Error" theme={:red} class="mt-8">
|
||||
<.notice title="Integration error" theme={:red} class="mt-8">
|
||||
<%= case error do %>
|
||||
<% "invalid_grant" -> %>
|
||||
Invalid Grant error returned from Google.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
} />
|
||||
|
||||
<div class="flow-root">
|
||||
<ul class="divide-y divide-gray-200 dark:divide-gray-600">
|
||||
<ul class="divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<%= for membership <- @memberships do %>
|
||||
<li class="py-4" id={"membership-#{membership.user.id}"}>
|
||||
<div class="flex items-center space-x-4">
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
</div>
|
||||
|
||||
<.dropdown>
|
||||
<:button class="bg-transparent text-gray-800 dark:text-gray-100 hover:bg-gray-50 dark:hover:bg-gray-700 focus-visible:outline-gray-100 whitespace-nowrap truncate inline-flex items-center gap-x-2 font-medium rounded-md px-3.5 py-2.5 text-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:bg-gray-400 dark:disabled:text-white dark:disabled:text-gray-400 dark:disabled:bg-gray-700">
|
||||
<:button class="bg-transparent text-gray-800 dark:text-gray-100 hover:bg-gray-50 dark:hover:bg-gray-800 focus-visible:outline-gray-100 whitespace-nowrap truncate inline-flex items-center gap-x-2 font-medium rounded-md px-3.5 py-2.5 text-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:bg-gray-400 dark:disabled:text-white dark:disabled:text-gray-400 dark:disabled:bg-gray-700">
|
||||
{site_role(membership)}
|
||||
<Heroicons.chevron_down mini class="size-4 mt-0.5" />
|
||||
</:button>
|
||||
|
|
@ -111,7 +111,7 @@
|
|||
membership.user.id
|
||||
)
|
||||
}
|
||||
class="text-red-600 hover:text-red-600"
|
||||
class="!text-red-600 hover:text-red-600 dark:!text-red-500 dark:hover:!text-red-400"
|
||||
method="delete"
|
||||
disabled={@site_role not in [:owner, :admin]}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
conn={@conn}
|
||||
>
|
||||
<:title>
|
||||
Custom Properties
|
||||
Custom properties
|
||||
</:title>
|
||||
<:subtitle>
|
||||
Attach Custom Properties when sending a Pageview or an Event to
|
||||
Attach custom properties when sending a pageview or an event to
|
||||
create custom metrics.
|
||||
</:subtitle>
|
||||
|
||||
|
|
|
|||
|
|
@ -144,14 +144,14 @@
|
|||
rows="6"
|
||||
readonly="readonly"
|
||||
onclick="this.select()"
|
||||
class="block w-full border-gray-300 dark:border-gray-700 resize-none text-sm shadow-xs focus:ring-indigo-500 focus:border-indigo-500 rounded-md dark:bg-gray-900 dark:text-gray-300"
|
||||
class="block w-full border-gray-300 dark:border-gray-750 resize-none text-sm shadow-xs focus:ring-indigo-500 focus:border-indigo-500 rounded-md dark:bg-gray-750 dark:text-gray-300"
|
||||
></textarea>
|
||||
<a
|
||||
onclick="var textarea = document.getElementById('embed-code'); textarea.focus(); textarea.select(); document.execCommand('copy');"
|
||||
href="javascript:void(0)"
|
||||
class="text-sm text-indigo-500 no-underline hover:underline"
|
||||
>
|
||||
<Heroicons.document_duplicate class="h-5 w-5 absolute text-indigo-700 top-3 right-3" />
|
||||
<Heroicons.document_duplicate class="size-5 absolute text-indigo-600 hover:text-indigo-700 dark:text-indigo-500 dark:hover:text-indigo-400 top-3 right-3 transition-colors duration-150" />
|
||||
</a>
|
||||
</div>
|
||||
</.tile>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21 11H1" stroke="#90A1B9" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11 21C16.7143 15.5578 16.7143 6.44218 11 1" stroke="#90A1B9" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11.0006 21C5.28627 15.5578 5.28627 6.44218 11.0006 1" stroke="#90A1B9" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11 21C16.5228 21 21 16.5228 21 11C21 5.47715 16.5228 1 11 1C5.47715 1 1 5.47715 1 11C1 16.5228 5.47715 21 11 21Z" stroke="#90A1B9" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M21 11H1" stroke="#a1a1aa" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11 21C16.7143 15.5578 16.7143 6.44218 11 1" stroke="#a1a1aa" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11.0006 21C5.28627 15.5578 5.28627 6.44218 11.0006 1" stroke="#a1a1aa" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11 21C16.5228 21 21 16.5228 21 11C21 5.47715 16.5228 1 11 1C5.47715 1 1 5.47715 1 11C1 16.5228 5.47715 21 11 21Z" stroke="#a1a1aa" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 719 B After Width: | Height: | Size: 719 B |
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="#64748b"><path d="M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z"></path><path d="M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z"></path></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="#71717a"><path d="M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z"></path><path d="M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 496 B After Width: | Height: | Size: 496 B |
|
|
@ -23,10 +23,10 @@ defmodule PlausibleWeb.Storybook.Button do
|
|||
slots: ["Click me!"]
|
||||
},
|
||||
%Variation{
|
||||
id: :bright,
|
||||
description: "Bright button",
|
||||
id: :secondary,
|
||||
description: "Secondary button",
|
||||
attributes: %{
|
||||
"theme" => "bright"
|
||||
"theme" => "secondary"
|
||||
},
|
||||
slots: ["Click me!"]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1605,7 +1605,7 @@ defmodule PlausibleWeb.SiteControllerTest do
|
|||
test "shows form for new shared link", %{conn: conn, site: site} do
|
||||
conn = get(conn, "/sites/#{site.domain}/shared-links/new")
|
||||
|
||||
assert html_response(conn, 200) =~ "New Shared Link"
|
||||
assert html_response(conn, 200) =~ "New shared link"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ defmodule PlausibleWeb.Live.GoalSettings.FormTest do
|
|||
assert element_exists?(html, ~s/a#event-tab/)
|
||||
|
||||
pageview_tab = lv |> element(~s/a#pageview-tab/) |> render_click()
|
||||
assert pageview_tab =~ "Page Path"
|
||||
assert pageview_tab =~ "Page path"
|
||||
|
||||
event_tab = lv |> element(~s/a#event-tab/) |> render_click()
|
||||
assert event_tab =~ "Event Name"
|
||||
assert event_tab =~ "Event name"
|
||||
end
|
||||
|
||||
test "can navigate to scroll tab if scroll_depth feature visible for site/user",
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ defmodule PlausibleWeb.Live.PropsSettingsTest do
|
|||
conn = get(conn, "/#{site.domain}/settings/properties")
|
||||
|
||||
resp = html_response(conn, 200)
|
||||
assert resp =~ "Attach Custom Properties"
|
||||
assert resp =~ "Attach custom properties"
|
||||
|
||||
assert element_exists?(
|
||||
resp,
|
||||
|
|
@ -182,7 +182,7 @@ defmodule PlausibleWeb.Live.PropsSettingsTest do
|
|||
lv = get_liveview(conn, site)
|
||||
html = lv |> element(~s/button[phx-click="add-prop"]/) |> render_click()
|
||||
|
||||
assert html =~ "Add Property for #{site.domain}"
|
||||
assert html =~ "Add property for #{site.domain}"
|
||||
|
||||
assert element_exists?(
|
||||
html,
|
||||
|
|
|
|||
Loading…
Reference in New Issue