diff --git a/browser-extension/plugin/.env.development b/browser-extension/plugin/.env.development
index a41444a5..845728b3 100644
--- a/browser-extension/plugin/.env.development
+++ b/browser-extension/plugin/.env.development
@@ -1,4 +1,4 @@
ENVIRONMENT=development
LOCAL_STORAGE_NAME=ogbvData
-API_URL=http://localhost:3000
+API_URL=http://localhost:4000
MEDIA_URL=https://uli-media.tattle.co.in
\ No newline at end of file
diff --git a/browser-extension/plugin/src/api.js b/browser-extension/plugin/src/api.js
new file mode 100644
index 00000000..b4c43452
--- /dev/null
+++ b/browser-extension/plugin/src/api.js
@@ -0,0 +1,21 @@
+import axios from "axios";
+import config from "./config";
+
+const { API_URL } = config;
+
+export async function userLogin({email, password}){
+
+ console.log("INSIDE USERLOGIN: ")
+ try {
+ const response = await axios.post(`${API_URL}/api/auth/login`, {
+ email,
+ password
+ });
+ console.log("RESPONSE IS: ",response)
+ console.log('Login successful:', response.data);
+ return response.data;
+ } catch (error) {
+
+ throw error;
+ }
+}
diff --git a/browser-extension/plugin/src/ui-components/pages/App.jsx b/browser-extension/plugin/src/ui-components/pages/App.jsx
index 410c3521..1ee00b7d 100644
--- a/browser-extension/plugin/src/ui-components/pages/App.jsx
+++ b/browser-extension/plugin/src/ui-components/pages/App.jsx
@@ -46,6 +46,7 @@ export function App() {
async function navigatePreferences() {
try {
const userData = await getUserData();
+ console.log("USER DATA: ", userData)
const preferenceData = await getPreferenceData();
if (!ignore) {
diff --git a/browser-extension/plugin/src/ui-components/pages/Debug.jsx b/browser-extension/plugin/src/ui-components/pages/Debug.jsx
index 77ade592..d00902f2 100644
--- a/browser-extension/plugin/src/ui-components/pages/Debug.jsx
+++ b/browser-extension/plugin/src/ui-components/pages/Debug.jsx
@@ -9,7 +9,7 @@ import {
TextInput,
Heading
} from 'grommet';
-import { UserContext } from '../atoms/AppContext';
+import { UserContext, NotificationContext } from '../atoms/AppContext';
import repository from '../../repository';
import config from '../../config';
import { useTranslation } from 'react-i18next';
@@ -18,41 +18,126 @@ const { getUserData, getPreferenceData, setUserData, setPreferenceData } =
repository;
const { resetAccount } = Api;
import { Hide, View } from 'grommet-icons';
+import { userLogin } from '../../api';
export function Debug() {
const { user, setUser } = useContext(UserContext);
+ const { showNotification } = useContext(NotificationContext);
const [localStorageData, setLocalStorageData] = useState(undefined);
const { t, i18n } = useTranslation();
+ const [isResetChecked, setIsResetChecked] = useState(false);
- useEffect(() => {
- async function localStorage() {
- const userData = await getUserData();
- const preferenceData = await getPreferenceData();
- if (!ignore) {
- setLocalStorageData({
- user: userData,
- preference: preferenceData
- });
- }
- }
- let ignore = false;
- localStorage();
- return () => {
- ignore = true;
- };
- }, []);
-
- return {user ? Logged in. Settings : };
+ // useEffect(() => {
+ // async function localStorage() {
+ // const userData = await getUserData();
+ // const preferenceData = await getPreferenceData();
+ // if (!ignore) {
+ // setLocalStorageData({
+ // user: userData,
+ // preference: preferenceData
+ // });
+ // }
+ // }
+ // let ignore = false;
+ // localStorage();
+ // return () => {
+ // ignore = true;
+ // };
+ // }, []);
+
+ return (
+
+ {user ? (
+
+
+ Hello, {user?.email} !
+
+
+
+ Logout
+
+
+
+
+ setIsResetChecked(e.target.checked)
+ }
+ />
+
+
+
+ ) : (
+
+ )}
+
+ );
}
const LoginForm = () => {
const [reveal, setReveal] = useState(false);
const [formValues, setFormValues] = useState({ email: '', password: '' });
+ const { showNotification } = useContext(NotificationContext);
+ const { user, setUser } = useContext(UserContext);
- const handleSubmit = ({ value }) => {
+ async function handleSubmit({ value }) {
console.log('Form Submitted:', value);
- };
+
+ try {
+ let data = await userLogin(value);
+
+ console.log('LOGIN SUCCESS: ', data);
+ showNotification({
+ type: 'info',
+ message: 'Login Successful'
+ });
+
+ const { email, token } = data;
+
+ let setData = { email, token };
+
+ await setUserData(setData);
+ setUser(setData);
+ } catch (error) {
+ console.error(error);
+ if (error?.response?.status === 401) {
+ // console.log('UNAUTHORIZED', error);
+ showNotification({
+ type: 'error',
+ message: 'Unauthorized'
+ });
+ } else if (error?.response?.status >= 500) {
+ // console.log('UNAUTHORIZED', error);
+ showNotification({
+ type: 'error',
+ message: 'Server Error'
+ });
+ } else {
+ // console.log('SOMETHING WENT WRONG', error);
+ showNotification({
+ type: 'error',
+ message: 'Something Went Wrong'
+ });
+ }
+ }
+ }
return (
diff --git a/browser-extension/plugin/src/ui-components/pages/SlurCreate.jsx b/browser-extension/plugin/src/ui-components/pages/SlurCreate.jsx
index fb402d7e..68621214 100644
--- a/browser-extension/plugin/src/ui-components/pages/SlurCreate.jsx
+++ b/browser-extension/plugin/src/ui-components/pages/SlurCreate.jsx
@@ -36,7 +36,7 @@ export function SlurCreate() {
let newValue = slurCreatePluginToApi(value);
// console.log(newValue);
try {
- await createSlurAndCategory(user.accessToken, newValue);
+ await createSlurAndCategory("dea07e31-417c-4547-9208-57ff7fcf2da8", newValue);
navigate('/slur');
showNotification({
type: 'message',
diff --git a/uli-community/lib/uli_community/user_contribution.ex b/uli-community/lib/uli_community/user_contribution.ex
new file mode 100644
index 00000000..1a28bb84
--- /dev/null
+++ b/uli-community/lib/uli_community/user_contribution.ex
@@ -0,0 +1,104 @@
+defmodule UliCommunity.UserContribution do
+ @moduledoc """
+ The UserContribution context.
+ """
+
+ import Ecto.Query, warn: false
+ alias UliCommunity.Repo
+
+ alias UliCommunity.UserContribution.CrowdsourcedSlur
+
+ @doc """
+ Returns the list of crowdsourced_slurs.
+
+ ## Examples
+
+ iex> list_crowdsourced_slurs()
+ [%CrowdsourcedSlur{}, ...]
+
+ """
+ def list_crowdsourced_slurs do
+ Repo.all(CrowdsourcedSlur)
+ end
+
+ @doc """
+ Gets a single crowdsourced_slur.
+
+ Raises `Ecto.NoResultsError` if the Crowdsourced slur does not exist.
+
+ ## Examples
+
+ iex> get_crowdsourced_slur!(123)
+ %CrowdsourcedSlur{}
+
+ iex> get_crowdsourced_slur!(456)
+ ** (Ecto.NoResultsError)
+
+ """
+ def get_crowdsourced_slur!(id), do: Repo.get!(CrowdsourcedSlur, id)
+
+ @doc """
+ Creates a crowdsourced_slur.
+
+ ## Examples
+
+ iex> create_crowdsourced_slur(%{field: value})
+ {:ok, %CrowdsourcedSlur{}}
+
+ iex> create_crowdsourced_slur(%{field: bad_value})
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def create_crowdsourced_slur(attrs \\ %{}) do
+ %CrowdsourcedSlur{}
+ |> CrowdsourcedSlur.changeset(attrs)
+ |> Repo.insert()
+ end
+
+ @doc """
+ Updates a crowdsourced_slur.
+
+ ## Examples
+
+ iex> update_crowdsourced_slur(crowdsourced_slur, %{field: new_value})
+ {:ok, %CrowdsourcedSlur{}}
+
+ iex> update_crowdsourced_slur(crowdsourced_slur, %{field: bad_value})
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def update_crowdsourced_slur(%CrowdsourcedSlur{} = crowdsourced_slur, attrs) do
+ crowdsourced_slur
+ |> CrowdsourcedSlur.changeset(attrs)
+ |> Repo.update()
+ end
+
+ @doc """
+ Deletes a crowdsourced_slur.
+
+ ## Examples
+
+ iex> delete_crowdsourced_slur(crowdsourced_slur)
+ {:ok, %CrowdsourcedSlur{}}
+
+ iex> delete_crowdsourced_slur(crowdsourced_slur)
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def delete_crowdsourced_slur(%CrowdsourcedSlur{} = crowdsourced_slur) do
+ Repo.delete(crowdsourced_slur)
+ end
+
+ @doc """
+ Returns an `%Ecto.Changeset{}` for tracking crowdsourced_slur changes.
+
+ ## Examples
+
+ iex> change_crowdsourced_slur(crowdsourced_slur)
+ %Ecto.Changeset{data: %CrowdsourcedSlur{}}
+
+ """
+ def change_crowdsourced_slur(%CrowdsourcedSlur{} = crowdsourced_slur, attrs \\ %{}) do
+ CrowdsourcedSlur.changeset(crowdsourced_slur, attrs)
+ end
+end
diff --git a/uli-community/lib/uli_community/user_contribution/crowdsourced_slur.ex b/uli-community/lib/uli_community/user_contribution/crowdsourced_slur.ex
new file mode 100644
index 00000000..2c7ee87b
--- /dev/null
+++ b/uli-community/lib/uli_community/user_contribution/crowdsourced_slur.ex
@@ -0,0 +1,23 @@
+defmodule UliCommunity.UserContribution.CrowdsourcedSlur do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ schema "crowdsourced_slurs" do
+ field :label, :string
+ field :category, {:array, :string}
+ field :level_of_severity, Ecto.Enum, values: [:low, :medium, :high]
+ field :casual, :boolean, default: false
+ field :appropriated, :boolean, default: false
+ field :appropriation_context, :boolean, default: false
+ field :meaning, :string
+
+ timestamps(type: :utc_datetime)
+ end
+
+ @doc false
+ def changeset(crowdsourced_slur, attrs) do
+ crowdsourced_slur
+ |> cast(attrs, [:label, :level_of_severity, :casual, :appropriated, :appropriation_context, :meaning, :category])
+ |> validate_required([:label, :level_of_severity, :casual, :appropriated, :appropriation_context, :meaning, :category])
+ end
+end
diff --git a/uli-community/lib/uli_community_web/controllers/user_session_controller_api.ex b/uli-community/lib/uli_community_web/controllers/user_session_controller_api.ex
index 937428b0..eb495131 100644
--- a/uli-community/lib/uli_community_web/controllers/user_session_controller_api.ex
+++ b/uli-community/lib/uli_community_web/controllers/user_session_controller_api.ex
@@ -18,7 +18,7 @@ defmodule UliCommunityWeb.SessionControllerApi do
user ->
IO.inspect(user, label: "USER IS: ")
with {:ok, token} <- Token.sign(%{user_id: user.id}) do
- json(conn, %{token: token, message: "Token Generation Successful!"})
+ json(conn, %{token: token, message: "Token Generation Successful!", email: user.email})
else
_ ->
conn
diff --git a/uli-community/priv/repo/migrations/20250120074709_create_crowdsourced_slurs.exs b/uli-community/priv/repo/migrations/20250120074709_create_crowdsourced_slurs.exs
new file mode 100644
index 00000000..509fdae5
--- /dev/null
+++ b/uli-community/priv/repo/migrations/20250120074709_create_crowdsourced_slurs.exs
@@ -0,0 +1,19 @@
+defmodule UliCommunity.Repo.Migrations.CreateCrowdsourcedSlurs do
+ use Ecto.Migration
+
+ def change do
+
+ execute("CREATE TYPE level_of_severity AS ENUM ('low', 'medium', 'high')")
+ create table(:crowdsourced_slurs) do
+ add :label, :string
+ add :level_of_severity, :level_of_severity
+ add :casual, :boolean, default: false, null: false
+ add :appropriated, :boolean, default: false, null: false
+ add :appropriation_context, :boolean, default: false, null: false
+ add :meaning, :text
+ add :category, {:array, :string}
+
+ timestamps(type: :utc_datetime)
+ end
+ end
+end
diff --git a/uli-community/test/support/fixtures/user_contribution_fixtures.ex b/uli-community/test/support/fixtures/user_contribution_fixtures.ex
new file mode 100644
index 00000000..70cb6933
--- /dev/null
+++ b/uli-community/test/support/fixtures/user_contribution_fixtures.ex
@@ -0,0 +1,26 @@
+defmodule UliCommunity.UserContributionFixtures do
+ @moduledoc """
+ This module defines test helpers for creating
+ entities via the `UliCommunity.UserContribution` context.
+ """
+
+ @doc """
+ Generate a crowdsourced_slur.
+ """
+ def crowdsourced_slur_fixture(attrs \\ %{}) do
+ {:ok, crowdsourced_slur} =
+ attrs
+ |> Enum.into(%{
+ appropriated: true,
+ appropriation_context: true,
+ casual: true,
+ category: ["option1", "option2"],
+ label: "some label",
+ level_of_severity: "some level_of_severity",
+ meaning: "some meaning"
+ })
+ |> UliCommunity.UserContribution.create_crowdsourced_slur()
+
+ crowdsourced_slur
+ end
+end
diff --git a/uli-community/test/uli_community/user_contribution_test.exs b/uli-community/test/uli_community/user_contribution_test.exs
new file mode 100644
index 00000000..83bbcdd4
--- /dev/null
+++ b/uli-community/test/uli_community/user_contribution_test.exs
@@ -0,0 +1,71 @@
+defmodule UliCommunity.UserContributionTest do
+ use UliCommunity.DataCase
+
+ alias UliCommunity.UserContribution
+
+ describe "crowdsourced_slurs" do
+ alias UliCommunity.UserContribution.CrowdsourcedSlur
+
+ import UliCommunity.UserContributionFixtures
+
+ @invalid_attrs %{label: nil, category: nil, level_of_severity: nil, casual: nil, appropriated: nil, appropriation_context: nil, meaning: nil}
+
+ test "list_crowdsourced_slurs/0 returns all crowdsourced_slurs" do
+ crowdsourced_slur = crowdsourced_slur_fixture()
+ assert UserContribution.list_crowdsourced_slurs() == [crowdsourced_slur]
+ end
+
+ test "get_crowdsourced_slur!/1 returns the crowdsourced_slur with given id" do
+ crowdsourced_slur = crowdsourced_slur_fixture()
+ assert UserContribution.get_crowdsourced_slur!(crowdsourced_slur.id) == crowdsourced_slur
+ end
+
+ test "create_crowdsourced_slur/1 with valid data creates a crowdsourced_slur" do
+ valid_attrs = %{label: "some label", category: ["option1", "option2"], level_of_severity: "some level_of_severity", casual: true, appropriated: true, appropriation_context: true, meaning: "some meaning"}
+
+ assert {:ok, %CrowdsourcedSlur{} = crowdsourced_slur} = UserContribution.create_crowdsourced_slur(valid_attrs)
+ assert crowdsourced_slur.label == "some label"
+ assert crowdsourced_slur.category == ["option1", "option2"]
+ assert crowdsourced_slur.level_of_severity == "some level_of_severity"
+ assert crowdsourced_slur.casual == true
+ assert crowdsourced_slur.appropriated == true
+ assert crowdsourced_slur.appropriation_context == true
+ assert crowdsourced_slur.meaning == "some meaning"
+ end
+
+ test "create_crowdsourced_slur/1 with invalid data returns error changeset" do
+ assert {:error, %Ecto.Changeset{}} = UserContribution.create_crowdsourced_slur(@invalid_attrs)
+ end
+
+ test "update_crowdsourced_slur/2 with valid data updates the crowdsourced_slur" do
+ crowdsourced_slur = crowdsourced_slur_fixture()
+ update_attrs = %{label: "some updated label", category: ["option1"], level_of_severity: "some updated level_of_severity", casual: false, appropriated: false, appropriation_context: false, meaning: "some updated meaning"}
+
+ assert {:ok, %CrowdsourcedSlur{} = crowdsourced_slur} = UserContribution.update_crowdsourced_slur(crowdsourced_slur, update_attrs)
+ assert crowdsourced_slur.label == "some updated label"
+ assert crowdsourced_slur.category == ["option1"]
+ assert crowdsourced_slur.level_of_severity == "some updated level_of_severity"
+ assert crowdsourced_slur.casual == false
+ assert crowdsourced_slur.appropriated == false
+ assert crowdsourced_slur.appropriation_context == false
+ assert crowdsourced_slur.meaning == "some updated meaning"
+ end
+
+ test "update_crowdsourced_slur/2 with invalid data returns error changeset" do
+ crowdsourced_slur = crowdsourced_slur_fixture()
+ assert {:error, %Ecto.Changeset{}} = UserContribution.update_crowdsourced_slur(crowdsourced_slur, @invalid_attrs)
+ assert crowdsourced_slur == UserContribution.get_crowdsourced_slur!(crowdsourced_slur.id)
+ end
+
+ test "delete_crowdsourced_slur/1 deletes the crowdsourced_slur" do
+ crowdsourced_slur = crowdsourced_slur_fixture()
+ assert {:ok, %CrowdsourcedSlur{}} = UserContribution.delete_crowdsourced_slur(crowdsourced_slur)
+ assert_raise Ecto.NoResultsError, fn -> UserContribution.get_crowdsourced_slur!(crowdsourced_slur.id) end
+ end
+
+ test "change_crowdsourced_slur/1 returns a crowdsourced_slur changeset" do
+ crowdsourced_slur = crowdsourced_slur_fixture()
+ assert %Ecto.Changeset{} = UserContribution.change_crowdsourced_slur(crowdsourced_slur)
+ end
+ end
+end