Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: landing ui improvements #489

Merged
merged 4 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/safira/activities.ex
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ defmodule Safira.Activities do
def list_daily_activities(day) do
Activity
|> where([a], a.date == ^day)
|> order_by([a], a.time_start)
|> order_by([a], asc: a.time_start)
|> preload([:speakers, :category])
|> Repo.all()
end
Expand Down
7 changes: 2 additions & 5 deletions lib/safira/activities/speaker.ex
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,8 @@ defmodule Safira.Activities.Speaker.Socials do

def validate_linkedin(changeset) do
changeset
|> validate_format(
:linkedin,
~r/^[a-zA-Z0-9]{3,100}$/,
message: "not a valid linkedin handle"
)
|> validate_length(:linkedin, min: 3, max: 100, message: "not a valid linkedin handle")
|> validate_format(:linkedin, ~r/^\S+$/, message: "cannot contain spaces")
end

def validate_x(changeset) do
Expand Down
81 changes: 81 additions & 0 deletions lib/safira/event.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,29 @@ defmodule Safira.Event do
defp bool_to_string(true), do: "true"
defp bool_to_string(false), do: "false"

@doc """
Changes whether the registrations for the event are open

## Examples

iex> change_registrations_open(true)
:ok
"""
def change_registrations_open(registrations_open) do
Constants.set(
"registrations_open",
bool_to_string(registrations_open)
)
end

@doc """
Returns the event's start time.

## Examples

iex> get_event_start_time()
~U[2025-02-11T08:00:00Z]
"""
def get_event_start_time! do
case Constants.get("start_time") do
{:ok, start_time_str} ->
Expand All @@ -54,6 +70,14 @@ defmodule Safira.Event do
end
end

@doc """
Changes the event's start time.

## Examples

iex> change_event_start_time(~U[2025-02-11T08:00:00Z])
:ok
"""
def change_event_start_time(start_time) do
result = Constants.set("start_time", DateTime.to_iso8601(start_time))
broadcast_start_time_update("start_time", start_time)
Expand All @@ -76,6 +100,14 @@ defmodule Safira.Event do
Phoenix.PubSub.broadcast(@pubsub, "start_time", {config, value})
end

@doc """
Returns whether the event has started.

## Examples

iex> event_started?()
false
"""
def event_started? do
start_time = get_event_start_time!()
DateTime.compare(start_time, DateTime.utc_now()) == :lt
Expand All @@ -95,23 +127,72 @@ defmodule Safira.Event do
]
end

@doc """
Returns the active feature flags.

## Examples

iex> get_active_feature_flags()
["login_enabled", "schedule_enabled"]
"""
def get_active_feature_flags! do
feature_flag_keys()
|> Constants.get_many!()
|> Enum.filter(fn {_k, v} -> v == "true" end)
|> Enum.map(fn {k, _v} -> k end)
end

@doc """
Returns the feature flag.

Raises `Ecto.NoResultsError` if the flag does not exist.

## Examples

iex> get_feature_flag!("login_enabled")
true
"""
def get_feature_flag!(flag) do
with {:ok, value} <- Constants.get(flag), do: value == "true"
end

@doc """
Returns the feature flag.

## Examples

iex> get_feature_flag("login_enabled")
true
"""
def get_feature_flag(flag) do
case Constants.get(flag) do
{:ok, value} -> value == "true"
_ -> false
end
end

@doc """
Returns the feature flags.

## Examples

iex> get_feature_flags()
%{"login_enabled" => true, "schedule_enabled" => false}
"""
def get_feature_flags do
feature_flag_keys()
|> Enum.map(fn k -> with {:ok, v} <- Constants.get(k), do: {k, v} end)
|> Enum.into(%{})
end

@doc """
Changes the feature flags.

## Examples

iex> change_feature_flags([{"login_enabled", true}, {"schedule_enabled", false}])
:ok
"""
def change_feature_flags(flags) do
flags
|> Enum.each(fn {k, v} -> Constants.set(k, bool_to_string(v)) end)
Expand Down
11 changes: 10 additions & 1 deletion lib/safira_web/components/layouts/landing.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,14 @@
<.flash_group flash={@flash} />
<%= @inner_content %>
</main>
<.footer />
<.footer>
<:tip :if={
Map.get(assigns, :current_page, nil) in [:home, :schedule, :speakers, :faqs] and
Safira.Event.get_feature_flag("challenges_enabled")
}>
Have you checked out the
<.link class="underline" navigate={~p"/challenges"}>challenges</.link>
yet? 🏆
</:tip>
</.footer>
</div>
12 changes: 8 additions & 4 deletions lib/safira_web/controllers/error_html/404.html.heex
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<body class="bg-primary text-light font-iregular relative min-h-screen">
<div class="text-light font-iregular relative min-h-screen">
<.sparkles />
<.navbar
pages={SafiraWeb.Config.landing_pages()}
registrations_open?={Safira.Event.registrations_open?()}
/>
<main>
<body class="bg-primary text-light font-iregular relative min-h-screen">
<body>
<.sparkles />
<div class="flex w-full justify-center items-center flex-col py-48 font-terminal uppercase xl:px-[15rem] md:px-[8rem] px-[2.5rem]">
<h5 class="z-0 w-full text-accent text-9xl">404</h5>
Expand All @@ -15,5 +15,9 @@
</div>
</body>
</main>
<.footer />
</body>
<.footer>
<:tip>
Okay, let's get you back on track. <.link class="underline" navigate={~p"/"}>Go home</.link>?
</:tip>
</.footer>
</div>
19 changes: 15 additions & 4 deletions lib/safira_web/controllers/error_html/500.html.heex
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<body class="bg-primary text-light font-iregular relative min-h-screen">
<div class="text-light font-iregular relative min-h-screen">
<.sparkles />
<.navbar
pages={SafiraWeb.Config.landing_pages()}
registrations_open?={Safira.Event.registrations_open?()}
/>
<main>
<body class="bg-primary text-light font-iregular relative min-h-screen">
<body>
<.sparkles />
<div class="flex w-full justify-center items-center flex-col py-48 font-terminal uppercase xl:px-[15rem] md:px-[8rem] px-[2.5rem]">
<h5 class="z-0 w-full text-accent text-9xl">500</h5>
Expand All @@ -15,5 +15,16 @@
</div>
</body>
</main>
<.footer />
</body>
<.footer>
<:tip>
<.link
class="underline"
target="_blank"
href="https://github.com/cesium/safira/graphs/contributors"
>
Their
</.link>
fault.
</:tip>
</.footer>
</div>
2 changes: 1 addition & 1 deletion lib/safira_web/live/landing/challenges_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ defmodule SafiraWeb.Landing.ChallengesLive.Index do

@impl true
def mount(_params, _session, socket) do
{:ok, socket}
{:ok, assign(socket, :current_page, :challenges)}
end

@impl true
Expand Down
19 changes: 17 additions & 2 deletions lib/safira_web/live/landing/components/footer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ defmodule SafiraWeb.Landing.Components.Footer do

alias Safira.Event

slot :tip, required: false

def footer(assigns) do
~H"""
<footer class="xl:px-[15rem] md:px-[8rem] px-[2.5rem]">
<div class="flex flex-col justify-between gap-16 py-10 lg:flex-row">
<div class="flex flex-col justify-between gap-16 py-10 lg:flex-row items-center">
<div class="flex select-none items-start justify-center lg:justify-start">
<img src="/images/sei-logo.svg" width={100} height={100} alt="SEI Logo" />
<p class="pl-6 text-white font-semibold lg:flex-1">
Semana da <br /> Engenharia <br /> Informática
</p>
</div>

<div class="flex-2">
<div class="grid lg:grid-flow-col lg:auto-rows-max gap-8 grid-cols-1 lg:grid-rows-2 select-none justify-items-center whitespace-nowrap font-iregular text-sm text-white">
<%= for {link, idx} <- Enum.with_index(footer_links()) do %>
Expand All @@ -38,6 +39,20 @@ defmodule SafiraWeb.Landing.Components.Footer do
</div>
</div>
</div>
<div
:if={@tip != []}
class="hidden lg:flex flex-col items-center w-full justify-center absolute bottom-0 left-0 overflow-clip select-none"
>
<div class="group flex flex-col items-center justify-center">
<p class="bg-white text-black text-center p-2 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity">
<%= render_slot(@tip) %>
</p>
<img
src={~p"/images/star-struck-void.svg"}
class="w-32 h-32 translate-y-11 group-hover:translate-y-6 transition-transform"
/>
</div>
</div>
</footer>
"""
end
Expand Down
31 changes: 10 additions & 21 deletions lib/safira_web/live/landing/components/schedule.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ defmodule SafiraWeb.Landing.Components.Schedule do
<.schedule_table
date={fetch_current_date_from_params(assigns.params) || assigns.event_start_date}
filters={fetch_filters_from_params(assigns.params)}
descriptions_enabled={assigns.descriptions_enabled}
user_role={get_user_role(assigns.current_user)}
enrolments={assigns.enrolments}
myself={assigns.myself}
Expand All @@ -69,7 +68,7 @@ defmodule SafiraWeb.Landing.Components.Schedule do
",
else: "text-md m-1 items-center rounded-full border-2 px-12 py-2 text-center font-bold
text-white shadow-sm
hover:border-accent hover:text-accent px-8
hover:bg-white/20 px-8 transition-colors
"
}
patch={filter_url(@url, @current_day, @filters, category.id)}
Expand All @@ -93,7 +92,6 @@ defmodule SafiraWeb.Landing.Components.Schedule do
<% else %>
<.schedule_activity
activity={activity}
descriptions_enabled={@descriptions_enabled}
user_role={@user_role}
enrolments={@enrolments}
myself={@myself}
Expand All @@ -108,10 +106,7 @@ defmodule SafiraWeb.Landing.Components.Schedule do

defp schedule_activity(assigns) do
~H"""
<div
id={@activity.id}
class="mx-2 sm:w-full border-t border-white p-[10px] ml-[10px] relative hover:bg-white/10 transition-colors"
>
<div id={@activity.id} class="mx-2 sm:w-full border-t border-white p-[10px] ml-[10px] relative">
<div class="relative h-full">
<!-- Times -->
<p class="text-lg font-iregular font-bold text-white xs:text-xl">
Expand All @@ -127,17 +122,17 @@ defmodule SafiraWeb.Landing.Components.Schedule do
</span>
</p>
<!-- Speakers -->
<ul class="my-[0.4em] flex font-iregular text-sm text-gray-400 z-10 gap-2 sm:gap-0">
<ul class="my-[0.4em] flex font-iregular text-sm text-gray-400 z-10 gap-2 xl:gap-0">
<li
:for={{speaker, index} <- Enum.with_index(@activity.speakers, fn el, i -> {el, i} end)}
class="list-none sm:float-left"
class="list-none xl:float-left"
>
<%= if index == length(@activity.speakers) - 1 and length(@activity.speakers) != 1 do %>
<bdi class="ml-[5px] hidden sm:inline">
<bdi class="ml-[5px] hidden xl:inline">
<%= gettext("and") %>
</bdi>
<% else %>
<span class="hidden sm:inline">
<span class="hidden xl:inline">
<%= if index != 0, do: "," %>
</span>
<% end %>
Expand Down Expand Up @@ -187,11 +182,8 @@ defmodule SafiraWeb.Landing.Components.Schedule do
</div>
<!-- Expand -->
<button
:if={
@descriptions_enabled and not is_nil(@activity.description) and
@activity.description != ""
}
class="font-terminal uppercase w-16 select-none rounded-full bg-accent px-2 text-xl text-white hover:scale-110"
:if={not is_nil(@activity.description) and @activity.description != ""}
class="font-terminal uppercase w-16 select-none rounded-full px-2 text-xl text-white border border-white hover:bg-white/20 transition-colors"
phx-click={
JS.toggle(
to: "#schedule-#{@activity.id}",
Expand All @@ -214,10 +206,7 @@ defmodule SafiraWeb.Landing.Components.Schedule do

defp schedule_break(assigns) do
~H"""
<div
id={@activity.id}
class="mx-2 sm:w-full border-t border-white p-[10px] ml-[10px] relative hover:bg-white/10 transition-colors"
>
<div id={@activity.id} class="mx-2 sm:w-full border-t border-white p-[10px] ml-[10px] relative">
<div class="relative h-full flex flex-row justify-between items-center">
<p class="font-iregular text-xl text-white font-bold">
<%= @activity.title %>
Expand All @@ -237,7 +226,7 @@ defmodule SafiraWeb.Landing.Components.Schedule do
defp schedule_day(assigns) do
~H"""
<div class="flex sm:w-full select-none justify-center">
<div class="flex sm:w-full justify-between text-4xl xs:text-5xl sm:text-7xl lg:text-8xl xl:mx-20 xl:text-7xl">
<div class="flex w-full justify-between text-4xl xs:text-5xl sm:text-7xl lg:text-8xl xl:mx-20 xl:text-7xl">
<div class="right relative flex items-center justify-center mt-[0.15em]">
<.link
:if={Date.compare(@date, @event_start_date) in [:gt]}
Expand Down
1 change: 1 addition & 0 deletions lib/safira_web/live/landing/faqs_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ defmodule SafiraWeb.Landing.FAQLive.Index do
def mount(_params, _session, socket) do
{:ok,
socket
|> assign(:current_page, :faqs)
|> stream(:faqs, Event.list_faqs())}
end
end
1 change: 1 addition & 0 deletions lib/safira_web/live/landing/home_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ defmodule SafiraWeb.Landing.HomeLive.Index do

{:ok,
socket
|> assign(:current_page, :home)
|> assign(:tiers, Companies.list_tiers_with_companies())
|> assign(:event_start_date, Event.get_event_start_date())
|> assign(:event_end_date, Event.get_event_end_date())
Expand Down
Loading