@@ -32,6 +32,8 @@ defmodule AlgoraWeb.Org.JobLive do
32
32
|> assign ( :job , job )
33
33
|> assign ( :show_import_drawer , false )
34
34
|> assign ( :show_share_drawer , false )
35
+ |> assign ( :show_payment_drawer , false )
36
+ |> assign ( :payment_form , to_form ( % { "payment_type" => "stripe" } , as: :payment ) )
35
37
|> assign ( :current_tab , tab )
36
38
|> assign ( :bounty_form , to_form ( BountyForm . changeset ( % BountyForm { } , % { } ) ) )
37
39
|> assign ( :tip_form , to_form ( TipForm . changeset ( % TipForm { } , % { } ) ) )
@@ -55,12 +57,6 @@ defmodule AlgoraWeb.Org.JobLive do
55
57
{ :ok , push_navigate ( socket , to: ~p" /#{ handle } /jobs/#{ id } /applicants" ) }
56
58
end
57
59
58
- @ impl true
59
- def handle_params ( % { "tab" => "activate" , "org_handle" => handle , "id" => id } , _uri , socket ) do
60
- Algora.Admin . alert ( "Activation request received for #{ AlgoraWeb.Endpoint . url ( ) } /#{ handle } /jobs/#{ id } " , :info )
61
- { :noreply , redirect ( socket , external: AlgoraWeb.Constants . get ( :calendar_url ) ) }
62
- end
63
-
64
60
@ impl true
65
61
def handle_params ( % { "tab" => tab } , _uri , socket ) do
66
62
{ :noreply , assign ( socket , :current_tab , tab ) }
@@ -354,7 +350,7 @@ defmodule AlgoraWeb.Org.JobLive do
354
350
</ div >
355
351
< div class = "flex flex-col justify-center items-center text-center " >
356
352
< . button
357
- patch = { ~p " / #{ @ current_org . handle } /jobs/ #{ @ job . id } /activate " }
353
+ phx-click = " toggle_payment_drawer "
358
354
variant = "none "
359
355
class = "group bg-emerald-900/10 text-emerald-300 transition-colors duration-75 hover:bg-emerald-800/10 hover:text-emerald-300 hover:drop-shadow-[0_1px_5px_#34d39980] focus:bg-emerald-800/10 focus:text-emerald-300 focus:outline-none focus:drop-shadow-[0_1px_5px_#34d39980] border border-emerald-400/40 hover:border-emerald-400/50 focus:border-emerald-400/50 h-[8rem] "
360
356
size = "xl "
@@ -475,12 +471,17 @@ defmodule AlgoraWeb.Org.JobLive do
475
471
</ div >
476
472
</ . drawer_content >
477
473
</ . drawer >
474
+
475
+ { payment_drawer ( assigns ) }
478
476
"""
479
477
end
480
478
481
479
@ impl true
482
480
def handle_event ( "activate_subscription" , _params , socket ) do
483
- case Jobs . create_payment_session ( % { socket . assigns . job | email: socket . assigns . current_user . email } ) do
481
+ case Jobs . create_payment_session (
482
+ % { socket . assigns . job | email: socket . assigns . current_user . email } ,
483
+ socket . assigns . current_org . subscription_price
484
+ ) do
484
485
{ :ok , url } ->
485
486
Algora.Admin . alert ( "Payment session created for job posting: #{ socket . assigns . job . company_name } " , :info )
486
487
{ :noreply , redirect ( socket , external: url ) }
@@ -491,6 +492,16 @@ defmodule AlgoraWeb.Org.JobLive do
491
492
end
492
493
end
493
494
495
+ @ impl true
496
+ def handle_event ( "toggle_payment_drawer" , _ , socket ) do
497
+ socket =
498
+ if socket . assigns . current_org . subscription_price ,
499
+ do: assign ( socket , :show_payment_drawer , ! socket . assigns . show_payment_drawer ) ,
500
+ else: redirect ( socket , external: AlgoraWeb.Constants . get ( :calendar_url ) )
501
+
502
+ { :noreply , socket }
503
+ end
504
+
494
505
@ impl true
495
506
def handle_event ( "toggle_import_drawer" , _ , socket ) do
496
507
{ :noreply , assign ( socket , :show_import_drawer , ! socket . assigns . show_import_drawer ) }
@@ -617,6 +628,35 @@ defmodule AlgoraWeb.Org.JobLive do
617
628
{ :noreply , assign ( socket , :show_share_drawer , false ) }
618
629
end
619
630
631
+ @ impl true
632
+ def handle_event ( "close_payment_drawer" , _ , socket ) do
633
+ { :noreply , assign ( socket , :show_payment_drawer , false ) }
634
+ end
635
+
636
+ @ impl true
637
+ def handle_event ( "process_payment" , % { "payment" => % { "payment_type" => "stripe" } } , socket ) do
638
+ # Mock data for demonstration
639
+ case Jobs . create_payment_session (
640
+ % { socket . assigns . job | email: socket . assigns . current_user . email } ,
641
+ socket . assigns . current_org . subscription_price
642
+ ) do
643
+ { :ok , url } ->
644
+ { :noreply , redirect ( socket , external: url ) }
645
+
646
+ { :error , _reason } ->
647
+ { :noreply , put_flash ( socket , :error , "Something went wrong. Please try again." ) }
648
+ end
649
+ end
650
+
651
+ @ impl true
652
+ def handle_event ( "process_payment" , % { "payment" => % { "payment_type" => "wire" } } , socket ) do
653
+ # Mock successful wire initiation
654
+ { :noreply ,
655
+ socket
656
+ |> put_flash ( :info , "Wire transfer details have been sent to your email" )
657
+ |> assign ( :show_payment_drawer , false ) }
658
+ end
659
+
620
660
@ impl true
621
661
def handle_event ( _event , _params , socket ) do
622
662
{ :noreply , socket }
@@ -1429,4 +1469,145 @@ defmodule AlgoraWeb.Org.JobLive do
1429
1469
</ . button >
1430
1470
"""
1431
1471
end
1472
+
1473
+ defp payment_drawer ( assigns ) do
1474
+ ~H"""
1475
+ < . drawer show = { @ show_payment_drawer } on_cancel = { JS . push ( "close_payment_drawer" ) } direction = "right " >
1476
+ < . drawer_header >
1477
+ < . drawer_title > Activate Subscription</ . drawer_title >
1478
+ < . drawer_description >
1479
+ Choose your preferred payment method to activate your annual subscription
1480
+ </ . drawer_description >
1481
+ </ . drawer_header >
1482
+
1483
+ < . drawer_content :if = { @ current_org . subscription_price } class = "mt-4 " >
1484
+ < . form for = { @ payment_form } phx-submit = "process_payment " >
1485
+ < div class = "space-y-6 " >
1486
+ < div class = "grid grid-cols-2 gap-4 " phx-update = "ignore " id = "payment-form-tabs " >
1487
+ <%= for { label , value } <- [ { "Stripe" , "stripe" } , { "Wire Transfer" , "wire" } ] do %>
1488
+ < label class = { [
1489
+ "group relative flex cursor-pointer rounded-lg px-3 py-2 shadow-sm focus:outline-none" ,
1490
+ "border-2 bg-background transition-all duration-200 hover:border-primary hover:bg-primary/10" ,
1491
+ "border-border has-[:checked]:border-primary has-[:checked]:bg-primary/10"
1492
+ ] } >
1493
+ < . input
1494
+ type = "radio "
1495
+ name = "payment[payment_type] "
1496
+ checked = { @ payment_form [ :payment_type ] . value == value }
1497
+ value = { value }
1498
+ class = "sr-only "
1499
+ phx-click = {
1500
+ % JS { }
1501
+ |> JS . hide ( to: "#payment-details [data-tab]:not([data-tab=#{ value } ])" )
1502
+ |> JS . show ( to: "#payment-details [data-tab=#{ value } ]" )
1503
+ }
1504
+ />
1505
+ < span class = "flex flex-1 items-center justify-between " >
1506
+ < span class = "text-sm font-medium " > { label } </ span >
1507
+ < . icon
1508
+ name = "tabler-check "
1509
+ class = "invisible size-5 text-primary group-has-[:checked]:visible "
1510
+ />
1511
+ </ span >
1512
+ </ label >
1513
+ <% end %>
1514
+ </ div >
1515
+
1516
+ < div id = "payment-details " >
1517
+ < div data-tab = "stripe " >
1518
+ < . card >
1519
+ < . card_header >
1520
+ < . card_title > Stripe Payment</ . card_title >
1521
+ < . card_description > Pay with credit card or ACH using Stripe</ . card_description >
1522
+ </ . card_header >
1523
+ < . card_content >
1524
+ < div class = "space-y-4 " >
1525
+ < div class = "flex justify-between items-center " >
1526
+ < span class = "text-sm text-muted-foreground " > Annual Subscription</ span >
1527
+ < span class = "font-semibold font-display " >
1528
+ { Money . to_string! ( @ current_org . subscription_price ) }
1529
+ </ span >
1530
+ </ div >
1531
+ < div class = "flex justify-between items-center " >
1532
+ < span class = "text-sm text-muted-foreground " > Processing Fee (4%)</ span >
1533
+ < span class = "font-semibold font-display " >
1534
+ { Money . to_string! (
1535
+ Money . mult! ( @ current_org . subscription_price , Decimal . new ( "0.04" ) )
1536
+ ) }
1537
+ </ span >
1538
+ </ div >
1539
+ < div class = "border-t pt-4 flex justify-between items-center " >
1540
+ < span class = "font-semibold " > Total</ span >
1541
+ < span class = "font-semibold font-display " >
1542
+ { Money . to_string! (
1543
+ Money . mult! ( @ current_org . subscription_price , Decimal . new ( "1.04" ) )
1544
+ ) }
1545
+ </ span >
1546
+ </ div >
1547
+ </ div >
1548
+ </ . card_content >
1549
+ </ . card >
1550
+
1551
+ < div class = "pt-4 flex justify-end gap-4 " >
1552
+ < . button variant = "secondary " phx-click = "close_payment_drawer " type = "button " >
1553
+ Cancel
1554
+ </ . button >
1555
+ < . button type = "submit " >
1556
+ Continue to checkout
1557
+ </ . button >
1558
+ </ div >
1559
+ </ div >
1560
+
1561
+ < div data-tab = "wire " class = "hidden " >
1562
+ < . card >
1563
+ < . card_header >
1564
+ < . card_title > Wire Transfer Details</ . card_title >
1565
+ < . card_description > Send payment to the following account</ . card_description >
1566
+ </ . card_header >
1567
+ < . card_content >
1568
+ < div class = "space-y-4 " >
1569
+ < div class = "grid grid-cols-2 gap-2 text-sm " >
1570
+ < span class = "text-muted-foreground " > Bank Name:</ span >
1571
+ < span class = "font-medium " > Silicon Valley Bank</ span >
1572
+
1573
+ < span class = "text-muted-foreground " > Account Name:</ span >
1574
+ < span class = "font-medium " > Algora Inc</ span >
1575
+
1576
+ < span class = "text-muted-foreground " > Account Number:</ span >
1577
+ < span class = "font-medium " > XXXX-XXXX-1234</ span >
1578
+
1579
+ < span class = "text-muted-foreground " > Routing Number:</ span >
1580
+ < span class = "font-medium " > XXXXXX123</ span >
1581
+
1582
+ < span class = "text-muted-foreground " > SWIFT Code:</ span >
1583
+ < span class = "font-medium " > SVBKUS6S</ span >
1584
+
1585
+ < span class = "text-muted-foreground " > Amount:</ span >
1586
+ < span class = "font-medium font-display " >
1587
+ { Money . to_string! ( @ current_org . subscription_price ) }
1588
+ </ span >
1589
+ </ div >
1590
+ </ div >
1591
+ < p class = "text-sm text-muted-foreground pt-4 " >
1592
+ You will receive an invoice and receipt via email once you confirm
1593
+ </ p >
1594
+ </ . card_content >
1595
+ </ . card >
1596
+
1597
+ < div class = "pt-4 flex justify-end gap-4 " >
1598
+ < . button variant = "secondary " phx-click = "close_payment_drawer " type = "button " >
1599
+ Cancel
1600
+ </ . button >
1601
+ < . button type = "submit " >
1602
+ I have wired
1603
+ </ . button >
1604
+ </ div >
1605
+ </ div >
1606
+ </ div >
1607
+ </ div >
1608
+ </ . form >
1609
+ </ . drawer_content >
1610
+ </ . drawer >
1611
+ """
1612
+ end
1432
1613
end
0 commit comments